2012-08-31 3 views
3

지난 몇 시간 동안 Oracle Database에서 간단한 작업 (SQL Server의 경우) 중 가장 간단한 작업을 수행하려고합니다. ADO.NET을 사용하는 .NET 응용 프로그램. 불가능 해 보입니다.Oracle Sql Query 내에서 sql 변수의 값을 .NET 코드로 다시 반환

SQL 서버의 경우 나는 내가 SqlCommand 개체를 가지고 가정하면,이 간단한 작업을 할 것 테이블 된 table_1에 새 레코드를 삽입 것이며, 나는 "ID"변수에 새로운 ID를 다시 걸릴 것

comm.CommandText = @" 
    DECLARE @next_id INT 
    SET @next_id = (SELECT ISNULL(MAX(id_col),0) FROM TABLE_1) + 1 
    INSERT INTO TABLE_1 (id_col, col1, ...) VALUES (@next_id, val1, ...) 
    SELECT @next_id"; 
int id = Convert.ToInt32(comm.ExecuteScalar()); 

C# 코드.

네 가지 간단한 단계

  • 새 변수
  • 반환 변수의 값을 가진 레코드를 삽입 가능한 다음 ID
  • 에 변수
  • 설정을 선언

확인 Oracle 쿼리에서 변수를 선언 할 수있었습니다. 또한 나는 그것을 (가치있는) 줄 수 있다고 생각한다. (SELECT INTO로)

어떻게이 변수의 값을 다시 C#으로 되돌릴 수 있는가? Oracle SQL에서 변수의 값을 출력 스트림으로 어떻게 선택합니까?

여기에는 ID 열을 다시 가져 오는 더 좋은 방법이 있지만 그 점에 대해서는 의문의 여지가 없습니다. 그것은 완전히 다른 예일 수 있습니다. 질문은 간단합니다. : .NET app 내에서 실행될 oracle sql 스크립트 내에서 변수를 선언했습니다. 오라클 쿼리에서 변수 값을 다시 C#으로 가져올 수 있습니까? 위의 코드는 Oracle ADO.NET 쿼리와 동일합니까?

답변

4

당신은 ODP.NET (오라클의 오라클 데이터 액세스 구성 요소)를 사용하는 것이 좋습니다 :

이의 예는 다음과 같습니다. ODP.NET에서는 실행중인 프로 시저 또는 명령문의 매개 변수에 해당하는 매개 변수 방향 (input, inputoutput, output, returnvalue)을 설정할 수 있습니다. 이러한 예에서, I은 서열 및 트리거를 통해 DB에 의해 생성 된 ID이다하는 ReturnValue를 잡는있어 (자동적 멀리 .NET 응용 프로그램으로 작성하여 그 우려)

int event_id = 0; 
using (OracleConnection oraConn = new OracleConnection(connStr)) 
{ 
    string cmdText = @"insert into EVENT 
     (EVENT_NAME, EVENT_DESC) 
     values 
     (:EVENT_NAME, :EVENT_DESC) 
     RETURNING EVENT_ID INTO :EVENT_ID 
     "; 

    using (OracleCommand cmd = new OracleCommand(cmdText, oraConn)) 
    { 
     oraConn.Open(); 
     OracleTransaction trans = oraConn.BeginTransaction(); 
     try 
     { 
      OracleParameter prm = new OracleParameter(); 
      cmd.BindByName = true; 
      prm = new OracleParameter("EVENT_NAME", OracleDbType.Varchar2); 
      prm.Value = "SOME NAME"; cmd.Parameters.Add(prm); 

      prm = new OracleParameter("EVENT_DESC", OracleDbType.Varchar2); 
      prm.Value = "SOME DESC"; cmd.Parameters.Add(prm); 

      prm = new OracleParameter("EVENT_ID" 
            , OracleDbType.Int32 
            , ParameterDirection.ReturnValue); 
      cmd.Parameters.Add(prm); 

      cmd.ExecuteNonQuery(); 
      trans.Commit(); 
      // return value 
      event_id = ConvertFromDB<int>(cmd.Parameters["EVENT_ID"].Value); 
     } 
     catch 
     { 
      trans.Rollback(); 
      throw; 
     } 
     finally 
     { 
      trans.Dispose(); 
     } 
     oraConn.Close(); 
    } 
} 

ConvertFromDB 반환 값을 .NET에 상응하는 것으로 변환하는 제네릭 일뿐입니다 (이 경우 int).

희망이 있습니다.

편집 : 당신은 쉽게 값의 배열을 바인딩 (및 반환 값의 배열 검색) ODP.NET의 수

:

using (OracleConnection oraConn = new OracleConnection(connStr)) 
{ 
    string cmdText = @"insert into TEST_EVENT 
     (EVENT_NAME, EVENT_DESC) 
     values 
     (:EVENT_NAME, :EVENT_DESC) 
     RETURNING EVENT_ID INTO :EVENT_ID 
     "; 

    using (OracleCommand cmd = new OracleCommand(cmdText, oraConn)) 
    { 
     oraConn.Open(); 
     OracleTransaction trans = oraConn.BeginTransaction(); 
     try 
     { 
      string[] event_names = new string[2]; 
      string[] event_descs = new string[2]; 
      int[] event_ids = new int[2]; 

      event_names[0] = "Event1"; 
      event_descs[0] = "Desc1"; 

      event_names[1] = "Event2"; 
      event_descs[1] = "Desc2"; 

      OracleParameter prm = new OracleParameter(); 
      cmd.Parameters.Clear(); 
      cmd.ArrayBindCount = 2; 
      cmd.BindByName = true; 

      prm = new OracleParameter("EVENT_NAME", OracleDbType.Varchar2); 
      prm.Value = event_names; cmd.Parameters.Add(prm); 

      prm = new OracleParameter("EVENT_DESC", OracleDbType.Varchar2); 
      prm.Value = event_descs; cmd.Parameters.Add(prm); 

      prm = new OracleParameter("EVENT_ID" 
            , OracleDbType.Int32 
            , ParameterDirection.ReturnValue); 
      cmd.Parameters.Add(prm); 


      cmd.ExecuteNonQuery(); 
      trans.Commit(); 
      // get return values 

      event_ids = (int[])(cmd.Parameters["EVENT_ID"].Value); 
     } 
     catch 
     { 
      trans.Rollback(); 
      throw; 
     } 
     finally 
     { 
      trans.Dispose(); 
     } 
     oraConn.Close(); 
    } 
} 
+0

글쎄, 실제로는 비록, 질문에 대답하지 않습니다 도움이됩니다. 문제는 SQL 스크립트 내에서 선언되고 초기화 된 변수 (매개 변수 아님)의 값을 C# 코드로 가져 오는 방법입니다. 하지만 묻고 싶습니다. 1) 제공하는 솔루션이 DB의 스키마를 변경합니까? 2) insert 문은 항상 Return Parameter에 id를 출력합니까? 3) 스크립트에 두 개의 INSERT가있는 것은 어떨까요? 어느 아이디가 반환됩니까? –

+0

또한 자동 증가 전략 (시퀀스 또는 기타)이없는 테이블은 어떻습니까? 그런 경우에 어떻게 이드를 돌려 주겠습니까? (모든 것이 트랜잭션의 컨텍스트에서 실행된다면) –

+1

@Saysmaster는 값 배열을 바인딩하고 반환 값 배열을 가져 오는 것에 대한 위의 편집 내용을 확인합니다. id 값에 관해서는 insert 문에 ID 값을 제공해야하며 그렇지 않으면 오라클이 트리거/연속 접근을 통해 생성하고 리턴합니다. – tbone