我需要确保在并发环境中,我将避免在同一个SQL Server表中重复插入2个。
为了做到这一点,首先,我尝试使用:
执行SELECT
WITH (UPDLOCK, ROWLOCK)
例如:
SELECT *
FROM Products p WITH (UPDLOCK, ROWLOCK)
WHERE p.groupId = ?1 AND p.classId = ?2
在此之后如果上面的select在同一个事务中返回0条记录,我会执行INSERT
语句。
这种方法是否可以防止空表上的重复项与p.groupId = ?1 AND p.classId = ?2
相同的产品?
如果不是,应该如何实施以避免重复?
答案 0 :(得分:3)
如果要对表进行插入,并且要确保不超过1行具有相同的groupId和classId,我建议您在创建表时使用Unique约束。例如:
CREATE TABLE Products (
groupId int NOT NULL,
classId int NOT NULL,
...
CONSTRAINT UC_GroupClassID UNIQUE (groupId, classId)
);
或者,您可以将表格改为:
ALTER TABLE Products
ADD CONSTRAINT UC_GroupClassID UNIQUE (groupId, classId)
您可以在以下网址找到更多信息:
https://docs.microsoft.com/en-us/sql/relational-databases/tables/create-unique-constraints
答案 1 :(得分:1)
根据您的评论,您希望在记录已存在时进行更新。合并声明是为此而设计的。我建议将传入的数据存储到临时表或表变量,然后发出合并。
请参阅此链接以获取我将在此处发布的示例。只需更改表名称和匹配条件。
https://technet.microsoft.com/en-us/library/bb522522(v=sql.105).aspx
MERGE Target AS T
USING Source AS S
ON (T.EmployeeID = S.EmployeeID)
WHEN NOT MATCHED BY TARGET AND S.EmployeeName LIKE 'S%'
THEN INSERT(EmployeeID, EmployeeName) VALUES(S.EmployeeID, S.EmployeeName)
WHEN MATCHED
THEN UPDATE SET T.EmployeeName = S.EmployeeName
WHEN NOT MATCHED BY SOURCE AND T.EmployeeName LIKE 'S%'
THEN DELETE
OUTPUT $action, inserted.*, deleted.*;