SQL Server存储过程实现仅插入不存在的表记录
实现SQL Server存储过程:仅当记录不存在时插入
嘿,这个需求在日常开发里太常见了,我给你两种实用的实现方案,你可以根据自己的场景来选:
方案一:使用IF NOT EXISTS判断(简单直观)
这种方法逻辑清晰,适合并发不高的场景,先检查目标wordId是否存在,不存在就执行插入:
CREATE PROCEDURE InsertWordIfNotExists @wordId INT, @word NVARCHAR(100) AS BEGIN SET NOCOUNT ON; -- 避免返回影响行数的额外信息 -- 检查wordId是否不存在 IF NOT EXISTS (SELECT 1 FROM Words WHERE wordId = @wordId) BEGIN -- 执行插入 INSERT INTO Words (wordId, word) VALUES (@wordId, @word); END END
说明:
- 把
Words替换成你的实际表名 SET NOCOUNT ON是好习惯,能减少不必要的网络传输- 这种方法的小局限是高并发场景下可能出现竞态条件——比如两个会话同时检查同一个
wordId都发现不存在,然后都执行插入,导致重复数据。如果你的系统并发量不高,这个问题可以忽略;如果需要强一致性,看下面的方案。
方案二:使用MERGE语句(原子操作,并发安全)
MERGE是SQL Server支持的原子性操作,检查和插入一步完成,从根本上避免竞态条件,适合高并发场景:
CREATE PROCEDURE InsertWordIfNotExists @wordId INT, @word NVARCHAR(100) AS BEGIN SET NOCOUNT ON; MERGE INTO Words AS Target USING (VALUES (@wordId, @word)) AS Source (wordId, word) ON Target.wordId = Source.wordId -- 如果匹配不到(即记录不存在),执行插入 WHEN NOT MATCHED THEN INSERT (wordId, word) VALUES (Source.wordId, Source.word); END
说明:
- MERGE语句将检查和插入合并为一个原子操作,数据库会保证这个过程的一致性
- 同样记得替换
Words为你的实际表名 - 这种写法更简洁也更安全,推荐在需要保证数据唯一性的场景下使用
额外提醒一句:如果你的业务要求wordId必须唯一,最好给wordId字段加上主键约束或者唯一约束,这样即使存储过程出现意外,数据库层面也能阻止重复数据插入,双重保障。
内容的提问来源于stack exchange,提问作者iamal
相关产品推荐
相关产品推荐

