【问题标题】:If Not Exists Insert inside a loop which record updatedIf Not Exists 在更新记录的循环内插入
【发布时间】:2018-12-24 01:10:59
【问题描述】:

使用 SQL Server 2016,我在循环中有一个非常简单的 IF NOT Exists ..... INSERT statement。正如预期的那样,这很好用。有没有办法确定哪些记录存在因此没有插入,哪些记录不存在因此在不使用第二个查询的情况下插入?

我可以通过执行 SELECT 轻松实现这一点,然后如果没有找到我插入,但是这是我循环中的两个查询。如果可能,我想尝试在一个查询中实现这一目标?

这样做的目的是向用户展示:

  1. Chris 现已注册英语
  2. Chris 现在就读数学
  3. Chris 已经就读于科学专业

所以 1 和 2 不存在因此插入。 3 确实存在因此没有插入

jon 的这个循环的例子:

    for i = 0 to numOfCourses
        sql = IF NOT EXISTS (SELECT fieldName from tableName 
        WHERE courseID = 1 AND directoryID = 2)
        BEGIN
        INSERT INTO tableName(courseID, directoryID)
        VALUES (1, 2) 
        END 
    next

【问题讨论】:

  • 请发布您已经构建的代码。请提供样本数据和期望的结果。我用这个工具生成ASCII tables
  • @JonJaussi 我已经发布了我想要的结果。我拥有的代码只是一个如果不存在则在循环中插入查询。我现在已经包含了一个这样的例子
  • 也许这有帮助:stackoverflow.com/questions/7917695/…,使用OUTPUT 子句。
  • 我看不出您想要的输出与您提供的查询有什么关系。如何区分“已注册”和“已注册”?
  • 扩展 hlg 的建议:基于集合的解决方案将使用 数字表 来提供值,因此只需要一个 insertoutput 子句可用于捕获插入了哪些行。结果可以与 numbers 表连接以识别未插入的行,即已经存在的行。旁白:奇怪的是,您没有在循环中使用i,您只是不断尝试一遍又一遍地处理同一行。

标签: sql sql-server tsql sql-server-2016


【解决方案1】:

@@ROWCOUNT 在这里可能很有用...

INSERT INTO tableName(courseID, directoryID)
SELECT 1 as courseID, 2 as directoryID 
WHERE NOT EXISTS (SELECT 1 FROM tableName WHERE courseID = 1 AND directoryID = 2);

SELECT CASE WHEN @@ROWCOUNT = 1 
            THEN 'Chris is now enrolled in English'
            ELSE 'Chris was already enrolled in English' END as my_result;

使用这种方法,您不需要循环中的 IF 语句或对现有记录的初始检查。

我改编了这个答案:How to get number of rows inserted by a transaction

希望对你有帮助。

【讨论】:

  • 嗨乔恩我想你错过了理解我的问题。使用 IF NOT EXISTS INSERT 有没有办法识别哪些记录存在因此没有插入,哪些记录不存在因此在不使用第二个查询的情况下插入?
  • @Mat41 让我知道这是否更接近您正在寻找的内容
【解决方案2】:

您可以使用MERGE (Transact-SQL) 命令与OUTPUT Clause (Transact-SQL) 组合使用

Merge 将执行条件插入,OUTPUT 将返回/保存插入的记录。
然后,您只需将给定记录与插入的记录进行比较,以及插入集合中不存在的记录已经存在于表中。

DECLARE @InsertedNames AS TABLE (Name VARCHAR(200))
DECLARE @GivenNames AS TABLE (Name VARCHAR(200))
INSERT INTO @GivenNames VALUES ('One'), ('Two')

MERGE INTO TableName AS t  
USING (SELECT Name FROM @GivenNames) AS given (Name)  
    ON t.Name = given.Name  
WHEN NOT MATCHED THEN  
    INSERT (Name) VALUES (given.Name)  
OUTPUT inserted.Name INTO @InsertedNames;

-- return all names with result.
SELECT 'inserted', Name FROM @InsertedNames  
UNION ALL  
SELECT 'already existed', g.Name 
FROM @GivenNames g 
WHERE g.Name NOT IN (SELECT Name FROM @InsertedNames)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 2017-01-18
    相关资源
    最近更新 更多