我见过人们对这种逻辑有设计模式问题。
1 - 测试记录的存在。
2 - 如果不存在,则插入记录。
特别是如果并发发挥作用。根据隔离级别,您可能有重复的数据或密钥违规。
为什么不首先在 pname 和 pnumber 上放置一个主键。我假设你在谈论一个人表。
我的例子。
--
-- Setup sample table w/data
--
-- Sample table
create table #person
(
person_id int identity (1, 1),
person_name varchar(64) not null,
person_no varchar(16) not null
);
go
-- primary key
alter table #person
add primary key (person_no, person_name)
go
-- first insert works
insert into #person (person_name, person_no) values ('bilbo', 123)
go
解决的关键是捕获主键违规。根据您的业务逻辑,忽略此错误可能是好是坏。
我决定忽略这个问题。
--
-- Ignore primary key violations
--
-- Try these steps
BEGIN TRY
-- Second insert fails
insert into #person (person_name, person_no) values ('bilbo', 123)
END TRY
-- Error Handler
BEGIN CATCH
-- Ignore PK error
IF ERROR_NUMBER() <> 2627
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
END CATCH
此解决方案消除了重复条目,并且不报告 PK 违规。