2012-08-31 34 views
3

在過去的幾個小時裏,我試圖通過一個Oracle數據庫中的最簡單的東西(至少對於SQL SERVER)使用ADO.NET的.NET應用程序。這似乎不可能。從Oracle Sql查詢中返回一個sql變量的值返回到.NET代碼

對於SQL Server,我會做這個簡單的任務,假設我有一個SqlCommand對象

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()); 

這將插入一個新的記錄表TABLE_1,我會拿回來的新標識中的「ID」變量在C#代碼。

四個簡單的步驟

  • 聲明是一個變量
  • 設置爲下一個可用的ID
  • 新變量
  • 返回變量的值插入記錄

好我設法在Oracle查詢中聲明變量。我想(我想)我設法給它一個值(與選擇進入)

我怎樣才能得到這個變量的價值回來在C#?我如何將變量的值選擇到Oracle SQL中的輸出流?

我知道有更好的方法來獲取標識列,但這不是問題。這可能是一個完全不同的例子。問題很簡單。:我已經在一個oracle sql腳本中聲明瞭一個變量,該腳本將在.net應用程序中執行。 如何從oracle查詢中將變量的值返回給c#?以上代碼與Oracle ADO.NET查詢等效的是什麼?

回答

4

你要使用ODP.NET(Oracle的Oracle數據訪問組件):

這下面是一個例子。請注意,在ODP.NET中,您可以建立參數方向(輸入,輸入輸出,輸出,返回值),以與您正在運行的過程或語句的參數相對應。在這個例子中,我抓住一個返回值,其是由db經由序列和觸發產生的ID(其創建自動地儘可能的.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

嗯,其實這並沒有回答這個問題,即使這是有幫助的。問題是如何讓c#代碼在sql腳本中聲明和初始化的變量(不是參數)的值。 但我想問你, 1)你提供的解決方案是否改變了DB的模式? 2)插入語句是否總是在返回參數中輸出ID? 3)如何在腳本中使用兩個INSERT?哪個人的身份證被退回? –

+0

另外,表沒有自動增量策略(序列或任何它)是什麼?在這種情況下你會如何返回ID? (前提是一切都在事務的上下文中執行) –

+1

@Saysmaster請參閱我上面對綁定值數組(並獲取返回值數組)的編輯。至於id值,你可能需要在insert語句中提供ID值,或者你會讓Oracle產生它(通過觸發器/ seq方法),並返回給你。 – tbone