【发布时间】:2021-02-03 11:26:29
【问题描述】:
也许有人知道我可以检查什么:
using (var cnn = new SqlConnection(connection))
{
cnn.Open();
using (var cmd = new SqlCommand())
{
cmd.Connection = cnn;
cmd.CommandText = "IF EXISTS (SELECT * FROM kruserprofile WHERE lactorid=@1 AND strname=@2) " +
" UPDATE kruserprofile SET txtvalue=@3 WHERE lactorid=@1 AND strname=@2 " +
"ELSE " +
" INSERT INTO kruserprofile (lactorid, strname, txtvalue) " +
" VALUES (@1, @2, @3)";
cmd.CommandTimeout = 120;
cmd.Parameters.AddWithValue("@1", actorId);
cmd.Parameters.AddWithValue("@2", ident);
cmd.Parameters.AddWithValue("@3", _mXml.ToString());
cmd.ExecuteNonQuery();
}
cnn.Close();
}
正如您在这段代码中看到的那样,我会检查记录是否存在并更新或插入。
这在 SQL Server 系统上运行良好。
在 Azure SQL 上,我有时会这样做但无法重现错误:
Violation on PRIMARY KEY...,其中约束位于 lactorid 和 strname。
表:
CREATE TABLE dbo.kruserprofile (
lactorid int NOT NULL,
strname nvarchar(254) NOT NULL,
txtvalue nvarchar(max) NULL
);
GO
ALTER TABLE dbo.kruserprofile ADD CONSTRAINT PK__kruserpr__6E092EE804688C07 PRIMARY KEY (lactorid, strname);
GO
所以我没有找到任何原因,但有时似乎EXISTSreturns false 所以它尝试插入然后失败。知道我可以检查什么吗?
【问题讨论】:
-
这叫并发。检查和插入之间存在时间间隔。您也许可以使用
MERGE。 -
找到了这个sqlperformance.com/2020/09/locking/upsert-anti-pattern,它给了我所需要的一切......
-
@Charlieface 这不是我的问题,但无论如何都是好的提示!我也会对此进行重构,谢谢!
标签: sql-server azure-sql-database