需要在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);
}
}
}
有没有更好的方法来编程,如果是这样的话?
答案 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();
}
}