【问题标题】:Using Multiple IF NOT EXISTS Statements Inside A Single Query在单个查询中使用多个 IF NOT EXISTS 语句
【发布时间】:2014-09-22 20:01:33
【问题描述】:

我正在尝试针对 MSSQL 运行多 INSERT 查询,在该查询中我将大量记录插入到同一个表中。所以到目前为止我的查询看起来像这样:

INSERT INTO [dbo].[People] (Code, Name) VALUES(101,'Bob'), (102,'John'), (103,'Jane');

我想详细说明查询,以便它只会在记录不存在时插入记录。我知道我可以使用以下语句:

IF NOT EXISTS (SELECT * FROM [dbo].[People] WHERE Code = 101) BEGIN
INSERT INTO [dbo].[People] (Code, Name) VALUES(101,'Bob');
END

但是,我只能弄清楚如何将其应用于单个记录。 有没有办法可以在单个查询中运行多个“IF NOT EXISTS”语句?

【问题讨论】:

    标签: sql-server bulkinsert not-exists


    【解决方案1】:

    这里有几种方法:

    insert into [dbo].[People] (Code, Name) 
    select x.c, x.n
    from
    (
        select 101 c, 'Bob' n
        union select 102 c, 'Rob' n
    ) x
    where c in (select code from [dbo].[People])
    

    --或

    insert into [dbo].[People] (Code, Name) 
    select x.c, x.n
    from
    (
        select 101 c, 'Bob' n
        union select 102 c, 'Rob' n
    ) x
    where exists (select top 1 1 from [dbo].[People] p where p.code = x.c)
    

    或者,如果您想更高级,可以查看merge 语句,它允许您根据各种条件执行多项操作:

    http://blog.sqlauthority.com/2010/06/08/sql-server-merge-operations-insert-update-delete-in-single-execution/

    merge [dbo].[People] as target
    using 
    (
        select 101 c, 'Bob' n
        union select 102 c, 'Rob' n
    ) as source
    on source.c = target.code
    when not matched by source then
    insert(code,name) values (c, n);
    

    但是,对于您的用例,merge 可能过于复杂。当您想要执行其他操作时,该语句会很有用,例如更新存在的行但在不存在的地方插入新行。

    【讨论】:

    • 谢谢约翰。我试图了解 MERGE 语句,但我看不出它如何适用于同一个表中的不同 SELECT 语句。 MERGE 看起来是正确的方法,但他的示例将两个表合并在一起。我需要遍历一个表来检查每一行的代码。你能详细说明那个例子吗?
    • 当然 - 更新了一个示例 - 但是 merge 超出了您的要求;我只是在您有更复杂的需求但不知道该声明的情况下才提到它。
    • 好的,看起来 MERGE 不适合,所以使用您的第一个示例。不过只有一个问题:对于我的示例,我尝试使用两个字段(代码和名称)保持简单,但是,如果我想为每条记录插入 20 个字段,但只检查 ID 是否存在,我会将其他数据,因为我收到以下错误,并且您的示例使用 3 个不同的 SELECT 语句:“INSERT 语句的选择列表包含的项目少于插入列表。SELECT 值的数量必须与 INSERT 列的数量匹配”跨度>
    • 在插入语句的第一行,我将要插入的列命名为 (Code, Name)。在第二行,我列出了我希望放入这些字段x.c, x.n 的列。这些字段必须匹配(选择的列数和它们的命名顺序)。最后,提供要插入的数据的联合子查询 (select 101 c, 'Bob' n...) 必须提供值才能插入。
    • 感谢您的时间和帮助我解决这个问题。
    猜你喜欢
    • 2012-01-03
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    • 2012-06-05
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多