fli*_*p66 0 sql sql-server sql-server-2012
我必须把值插入到表与这些列:Id MasterId ZipCode Locality Value,CreatedTime,UpdatedTime
这3列定义了一个唯一值: MasterId ZipCode Locality
这些列上的数据库没有唯一约束,但我需要确保2个用户无法输入相同的数据.我无法更改T-SQL数据库架构.
当前的SQL:
INSERT INTO dbo.Carrier VALUES (?, ?, ?, ?, ?, GETDATE(), GETDATE())
Run Code Online (Sandbox Code Playgroud)
我的SQL更改:
IF NOT EXISTS
(
SELECT TOP 1 *
FROM dbo.Carrier
WHERE MasterId = ?
AND ZipCode = ?
AND Locality = ?
)
BEGIN
INSERT INTO dbo.Carrier VALUES (?, ?, ?, ?, ?, GETDATE(), GETDATE())
END
Run Code Online (Sandbox Code Playgroud)
这些更改适用于标准用户输入,但也有一个服务同时插入许多条目.有时,此服务将尝试以多线程方式插入数千个相同的唯一行,并且SQL具有竞争条件,因为它不是一个语句.这允许在同时执行2个语句时输入重复项.
有没有办法只在单个语句中不存在记录时插入?
我在UPDATE上没有这个问题,因为我可以做一个UpdatedTime没有改变的地方.
我会使用not exists以下单一语句执行此操作:
insert into dbo.Carrier (masterid, zipcode, locality, . . . )
select v.*
from (values (?, ?, ?, ... ), (?, ?, ?, ...)) v(masterid, zipcode, locality, . . .)
where not exists (select 1
from dbo.Carrier c
where c.masterid = v.masterid and c.zipcode = v.zipcode and c.locality = v.locality
);
Run Code Online (Sandbox Code Playgroud)
编辑:
如果要保护数据库以满足竞争条件,则应该让数据库进行保护.添加唯一索引/约束(masterid, zipcode, locality).然后你应该忽略任何违反约束的错误.