需要帮助如何记录如果存在更新其他插入

时间:2017-01-01 23:30:33

标签: c# oracle

需要在c#中进行编程的最佳方法。我正在尝试做一个if记录存在更新语句,否则插入语句,更新代码但仍然有插入/更新到数据库的问题。从此代码执行后,数据库中没有显示任何内容:

        String updCmdTxt = "UPDATE..";
        String insertCmdTxt = "INSERT ..";
        using (var scope = new TransactionScope())
        {
            using (var con = new OracleConnection(strConnection))
            {
                bool isDuplicate = false;
                var insertcmd = new OracleCommand(insertCmdTxt, con);
                try
                {


                    con.Open();
                          ......add params

                    insertcmd.ExecuteNonQuery();

                    con.Close();
                    Response.Redirect("test.aspx?Id=" + labelRID.Text);
                }
                catch (OracleException x)
                {
                    isDuplicate = true; //determine if the exception is about duplicates.
                    if (!isDuplicate)
                    {
                        throw;
                    }
                }
                finally
                {
                    insertcmd?.Dispose();
                }
                if (isDuplicate)
                {
                    using (var updcmd = new OracleCommand(updCmdTxt, con))

                        {

                       ....
                      updcmd.ExecuteNonQuery();


                    }
                }
                scope.Complete();
                Response.Redirect("test.aspx?Id=" + labelRID.Text);

            }
        }
    }

有没有更好的方法来编程,如果是这样的话?

2 个答案:

答案 0 :(得分:1)

使用MERGE语句,它结合了INSERT和UPDATE语句的功能。例如:

MERGE INTO CONTRACT_INFO c
  USING (SELECT 12345 FROM DUAL AS RID) d
    ON (d.RID = c.RID)
  WHEN MATCHED THEN
    UPDATE
      SET CONTRACT_INFO_FIELD_1 = something,
          CONTRACT_INFO_FIELD_2 = something_else
  WHEN NOT MATCHED THEN
    INSERT (RID, CONTRACT_INFO_FIELD_1, CONTRACT_INFO_FIELD_2)
    VALUES (d.RID, something, something_else);

祝你好运。

答案 1 :(得分:0)

很难在不知道所有细节的情况下提供建议,例如重复的可能性,每秒的请求数等等。我使用了一些常用技术来实现这一点:

  • 封装“upsert”的存储过程'流程。请参阅Oracle: how to UPSERT

  • 在客户端(您的案例)上实现upsert逻辑,但要保证启动事务所需的一致性,并在执行操作后关闭它。

如果表中的现有行更有可能,请在插入之前使用update以避免频繁出现异常。否则,您可以通过在更新前使用insert来优化工作流。

悲观解决方案

String updCmdTxt = "UPDATE ....";
String insertCmdTxt = "INSERT ....";
using (var scope = new TransactionScope())
{ 
   using (var con = new OracleConnection(conStr)){
      int rows;
      using (var updcmd = new OracleCommand(updCmdTxt, con)){
         //Set parameters ...
         rows = updcmd.ExecuteNonQuery();
      }
      //If update command did not affect any rows, insert
      if (rows == 0) {
         using (var insertcmd = new OracleCommand(insertCmdTxt, con)){
            // Set parameters...
            insertcmd.ExecuteNonQuery();
         }
      }
      scope.Complete();
   }
}

乐观解决方案

String updCmdTxt = "UPDATE ....";
String insertCmdTxt = "INSERT ....";
using (var scope = new TransactionScope())
{
    using (var con = new OracleConnection(conStr))
    {
        bool isDuplicate = false;
        var insertcmd = new OracleCommand(insertCmdTxt, con);
        try
        {
            // Set parameters...
            insertcmd.ExecuteNonQuery();
        }
        catch (OracleException x)
        {
            isDuplicate = ...; //determine if the exception is about duplicates.
            if (!isDuplicate)
            {
                throw;
            }
        }
        finally
        {
            insertcmd?.Dispose();
        }
        if (isDuplicate)
        {
            using (var updcmd = new OracleCommand(updCmdTxt, con))
            {
                //Set parameters ...
                updcmd.ExecuteNonQuery();
            }
        }
        scope.Complete();
    }
}