【问题标题】:SQL - Insert Where Not ExistsSQL - 在不存在的地方插入
【发布时间】: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 语句中遇到错误。为什么?如何实现我的目标?

【问题讨论】:

  • 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 答案...

标签: sql sql-server sql-server-2012


【解决方案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');
        

        【讨论】:

          猜你喜欢
          • 2021-09-16
          • 2018-09-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-24
          相关资源
          最近更新 更多