2017-12-06 10 views
1

私はカスケードでストアドプロシージャを実行しようとすると困っています。私はいくつかの助けが必要です。シナリオを見てみましょう:C#Oracle - 順番にストアドプロシージャを実行

私は父のテーブルを持って、私はOracleのSPを実行する方法を知っているが、私はドントのは、C#から今すぐ「REQUEST」と子テーブル、「REQUEST_DETAILS」

それを呼びましょうチェーンの中で2つを実行する方法を知っている、すべての終わりまでコミットせずに。

私は最初のストアドプロシージャがREQUESTデータと第2の1を挿入しますREQUEST.ID

と子供のデータを挿入するために開始するために生成されたREQUEST.IDを取得し、父・テーブル・データを挿入した後する必要が

REQUEST_DETAILデータを挿入しますが、何か問題が生じた場合は、すべてのトランザクションをロールバックします。

簡単な方法でこれを行う方法がありますか?

ここに私のコードがあります。

public Bool SaveRequest(Request newRequestData) 
{ 
    var connection = new connection(); 
    bool isSuccess = true; 

    OracleConnection Conn = connection._GetInstance(); 
    OracleCommand Cmd = new OracleCommand(); 
    Conn.Open(); 
    Cmd.Connection = Conn; 
    Cmd.CommandType = CommandType.StoredProcedure; 
    Cmd.CommandText = "PackageRequests.InsertNewRequest"; 
    Cmd.BindByName = true; 

    //IN PARAM 
    Cmd.Parameters.Add(new OracleParameter("P_LOCATION", OracleDbType.Varchar2, newRequestData.location, ParameterDirection.Input)); 
    Cmd.Parameters.Add(new OracleParameter("P_PCSTOTAL", OracleDbType.Int32, newRequestData.pcsTotal, ParameterDirection.Input)); 
    Cmd.Parameters.Add(new OracleParameter("P_STATUS", OracleDbType.Int32, newRequestData.status, ParameterDirection.Input)); 

    //Out Param 
    Cmd.Parameters.Add(new OracleParameter("P_NEW_ID", OracleDbType.Int32)).Direction = ParameterDirection.Output; 

    OracleTransaction transaction = Conn.BeginTransaction(IsolationLevel.ReadCommitted); 
    try 
    { 
     Cmd.ExecuteNonQuery(); 
     //New request_id 
     string newId = Convert.ToString(Cmd.Parameters["P_NEW_ID"].Value); 
     //Here I think goes the logic for execute the another procedure that will insert the data into REQUEST_DETAIL 
     /*** 
      foreach(var item in newRequestData.List) 
      { 
       //Insert request_detail_Data() 
      } 
     ***/ 

     //after all -- transaction.Commit(); 
    } 
    catch (OracleException ex) 
    { 
     //If something goes wrong rollback. 
     transaction.Rollback(); 
     isSuccess = false; 
    } 
    finally 
    { 
     Conn.Close(); 
    } 
    return isSuccess; 
} 
+0

挿入ストアドプロシージャには、データベースの最後に「コミット」が必要です。また、コードを編集して、追加のストアドプロシージャを呼び出す場所を表示できますか?別のパッケージを作成するか、Oracle側から追加のInsert文を追加できますか?これは、これをより効果的にするために、いくつかの異なる方法で行うことができます。 – MethodMan

答えて

0

私はこれを行うためのソリューションがトリックを別の関数にパラメータなどのOracle接続のパス上にあり、すべてが何かがロールバックに失敗した場合、最初の関数から、コミットして行われたときに見つけました。私は例を残して、誰かに役立つことを願っています。

public Bool SaveRequest(Request newRequestData) 
{ 
    var connection = new connection(); 
    bool isSuccess = true; 

    OracleConnection Conn = connection._GetInstance(); 
    OracleCommand Cmd = new OracleCommand(); 
    Conn.Open(); 
    Cmd.Connection = Conn; 
    Cmd.CommandType = CommandType.StoredProcedure; 
    Cmd.CommandText = "PackageRequests.InsertNewRequest"; 
    Cmd.BindByName = true; 

    // IN PARAMETERS... 
    Cmd.Parameters.Add(new OracleParameter("P_LOCATION", OracleDbType.Varchar2, newRequestData.location, ParameterDirection.Input)); 

    // OUT PARAMETER (Here I recover the master table ID) 
    Cmd.Parameters.Add(new OracleParameter("P_NEW_ID", OracleDbType.Int32)).Direction = ParameterDirection.Output; 

    // Initialize the Transaction 
    OracleTransaction transaction = Conn.BeginTransaction(IsolationLevel.ReadCommitted); 
    try 
    { 
     //Execute the first SP 
     Cmd.ExecuteNonQuery(); 
     string newId = Convert.ToString(Cmd.Parameters["P_NEW_ID"].Value); 

     // Calls another function and pass Oracle Connection, and master table ID like parameters 
     InsertRequestDetail(Conn, newId); 

     transaction.Commit(); 
    } 
    catch (OracleException ex) 
    { 
     //If something goes wrong rollback. 
     transaction.Rollback(); 
     isSuccess = false; 
    } 
    finally 
    { 
     Conn.Close(); 
    } 
    return isSuccess; 
} 

private void InsertRequestDetail(OracleConnection Conn, string newId) 
{ 

    OracleCommand Cmd = new OracleCommand(); 
    Cmd.Connection = Conn; 
    Cmd.CommandType = CommandType.StoredProcedure; 
    Cmd.CommandText = "MY_PACKAGE.AnotherSPName"; 
    Cmd.BindByName = true; 

    //IN - OUT PARAMS 
    Cmd.Parameters.Add(new OracleParameter("... 

    Cmd.ExecuteNonQuery(); 
} 
関連する問題