【问题标题】:C# Oracle - Execute Stored Procedures in sequenceC# Oracle - 按顺序执行存储过程
【发布时间】:2017-12-06 21:33:49
【问题描述】:

大家好,我在尝试在级联上执行存储过程时遇到了麻烦,我需要一些帮助。让我们看看场景:

我有一个父表,我们称之为“REQUEST”和一个子表,“REQUEST_DETAILS”

现在从 C# 开始,我知道如何执行 Oracle SP,但我不知道如何在链中执行两个,直到最后都没有提交。

我需要插入父表数据,得到生成的REQUEST.ID后开始插入带有REQUEST.ID的子表数据

所以第一个存储过程将插入 REQUEST 数据,第二个存储过程将插入 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;
}

【问题讨论】:

  • 您的插入存储过程在数据库端应该有Commit。您还可以编辑代码并显示您在哪里调用其他存储过程吗?您可以从 Oracle 端创建另一个包或添加其他插入语句吗?这可以通过几种不同的方式来提高效率。

标签: c# oracle stored-procedures


【解决方案1】:

我找到了解决这个问题的方法,就是将 Oracle Connection 之类的参数传递给另一个函数,当一切都完成后,如果某些事情回滚失败,则从初始函数开始。我留下一个例子,希望对某人有所帮助。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-29
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多