我有一些记录要通过存储过程“插入或更新”到SQL Server数据库中。这些记录具有全局唯一且稳定的ID,以及一堆值属性(大约十二个)。
检查插入是否足够简单 - 查看表中是否存在该键。
假设密钥确实存在,那么我需要检查现有记录是否包含与我传入过程的当前数据完全相同的值。目前我正在通过以下方式这样做:
SELECT @identical = CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END FROM Table
WHERE idCol = @newId
AND valueCol1 = @newValue1
AND valueCol2 = @newValue2
AND ...
这有效,但效率不高;我能够每秒插入大约70条记录,这比我预期的慢很多。
我的第一个想法是添加一个索引 - 但这将几乎索引表中的每一列。这甚至是有道理的还是仅仅是表的第二个副本? (如果相关,则ID列是群集PK。)
有没有明智的方法可以加快必须检查每列值的查询?我正在考虑使用某种哈希来检测重复项,但这会增加一些空间开销,sprocs的复杂性和小的(可接受的)误报的可能性,所以我更倾向于基于索引的解决方案或重写SQL如果一个存在。
答案 0 :(得分:2)
如果您使用的是SQL Server 2008,则可以使用MERGE语句
答案 1 :(得分:1)
不要事先测试,只要让where-clause为你工作。伪代码(您的语法可能会有所不同)
UPDATE thetable
SET valueCol1 = @newValue1
, valueCol2 = @newValue2
, ...
WHERE idCol = @newId
AND (valueCol1 <> @newValue1
OR valueCol2 <> @newValue2
OR ...
);
IF (ROWCOUNT > 0) RETURN;
INSERT INTO thetable (idCol, valueCol1, valueCol2, ...)
VALUES (@newId, @newValue1, @newValue2, ... )
WHERE NOT EXISTS ( SELECT * FROM thetable nx
WHERE nx.idCol = @newId
);
答案 2 :(得分:0)
这是一个经典的解决方案
if exists (select * from thetable where idCol = @newID)
begin
update ....
end
else
begin
insert ...
end