SQL - 在不存在的地方插入
Posted
技术标签:
【中文标题】SQL - 在不存在的地方插入【英文标题】:SQL - Insert Where Not Exists 【发布时间】:2017-10-16 21:15:21 【问题描述】:我有一个我认为完全微不足道的查询 - 如果不存在具有匹配 ID 的值,则将值插入表中:
BEGIN
INSERT INTO [dbo].[Contact_Categories](Contact_Category_ID, Description)
VALUES (1, 'Internal')
WHERE NOT EXISTS( SELECT * FROM [dbo].[Contact_Categories] WHERE Contact_Category_ID = 1)
END
我在 where 语句中遇到错误。为什么?如何实现我的目标?
【问题讨论】:
Check if a row exists, otherwise insert的可能重复BEGIN INSERT INTO [dbo].[Contact_Categories](Contact_Category_ID, Description) SELECT 1, 'Internal' FROM [dbo].[Contact_Categories] WHERE Contact_Category_ID <> 1) END
@PaulVarghese 它不存在什么?那么就没有Contact_Category_ID = 1
;
@VSO 检查 TZHX 答案...
【参考方案1】:
您的问题来自 WHERE
对 UPDATE/SELECT 有效,但 INSERT 只是不明白它的含义。
但是你可以解决这个问题。将您的代码更改为:
BEGIN
INSERT INTO [dbo].[Contact_Categories](Contact_Category_ID, Description)
SELECT 1, 'Internal'
WHERE NOT EXISTS( SELECT * FROM [dbo].[Contact_Categories] WHERE Contact_Category_ID = 1)
END
【讨论】:
这很优雅,比 IF 构造替代方案更好【参考方案2】:处理此问题的正确方法是使用唯一索引/约束:
create unique index unq_Contact_Categories_Category_Id on Contact_Categories(Contact_Category_ID);
然后数据库将保证该列的唯一性。这可以防止竞争条件。
您可以使用try
/catch
捕捉到这一点:
BEGIN TRY
INSERT INTO [dbo].[Contact_Categories](Contact_Category_ID, Description)
SELECT 1, 'Internal';
END TRY
BEGIN CATCH
PRINT 'Ooops'; -- you can even raise an error if you like.
END CATCH;
【讨论】:
【参考方案3】:为什么不用 If 语句?
IF NOT EXISTS
(select * from [dbo].[Contact_Categories] WHERE Contact_Category_ID = 1)
begin
insert into [dbo].[Contact_Categories] (Contact_Category_ID, Description)
values (1, 'Internal')
end
如果值存在,这样做的好处是不做任何事情。类似于此处提供的答案:SQL Server IF NOT EXISTS Usage?
【讨论】:
【参考方案4】:我愿意:
INSERT INTO [dbo].[Contact_Categories](Contact_Category_ID, Description)
VALUES (1, 'Internal')
WHERE 1 NOT IN ( SELECT Contact_Category_ID FROM [dbo].[Contact_Categories])
【讨论】:
【参考方案5】:尝试将您的查询替换为:
BEGIN
IF NOT EXISTS (SELECT * FROM [dbo].[Contact_Categories] WHERE Contact_Category_ID = 1)
INSERT INTO [dbo].[Contact_Categories](Contact_Category_ID,Description) VALUES (1, 'Internal')
END
【讨论】:
此查询必须在事务中以防止竞争条件,否则有人可能会在检查表和插入行之间插入一行。【参考方案6】:我也遇到了同样的问题,这是我的解决方案。
insert into Contact_Categories (Contact_Category_ID, Description)
select 1, 'Internal'
where not exists
(select * from Contact_Categories where Contact_Category_ID = 1 and Description = 'Internal');
【讨论】:
以上是关于SQL - 在不存在的地方插入的主要内容,如果未能解决你的问题,请参考以下文章