SQL Server Merge Upsert仅执行更新而不插入

时间:2015-09-25 13:01:09

标签: sql sql-server upsert

我想记录学生在门上刷牌时的动作。每次出现卡片ID和名称时,我想检查它是否是学生表中尚未存在的新组合。如果不存在,则插入一条新记录,其中FirstEntry和LastEntry是相同的日期,cardid和name是发送到相应参数的记录。如果已存在组合,则仅更新[LastEntry]字段。目前我的查询只是更新现有记录,这意味着只有[LastEntry]字段得到更新。对于更新,这是正常的。但是,它不会为新条目插入新记录。 CardID和Name是表格中的复合主键。

  • 我不想使用IF Exists(Select ...)方法进行实现 这个。
  • 我只想使用MERGE。
  • 此操作将在不使用任何临时表的情况下在同一个表上完成
  • 执行操作后,我想在更新或插入方案中查看受影响的记录。只显示以下字段[cardid,name,FirstEntry,LastEntry],而不显示表中的其他字段。
  • 该表包含其他我不想显示或返回的列。

这是我的声明,它只进行更新

            MERGE INTO
            Students AS T
        USING 
            (SELECT cardid,  name, FirstEntry, LastEntry from Students where cardid = @id and name = @name) AS S
        ON
            (S.cardid = T.cardid
            AND
            S.name = T.name)
        WHEN MATCHED THEN
            UPDATE SET LastEntry =  @DT
        WHEN NOT MATCHED THEN
            INSERT (cardid,  name, FirstEntry, LastEntry) VALUES(@id, @name, @DT, @DT )
        OUTPUT $action, S.cardid,  S.name, S.FirstEntry, S.LastEntry;

除了更新,我希望它能够影响插入以及新记录

1 个答案:

答案 0 :(得分:3)

您的using子句不应该查询Students表。这就是您要插入或更新新值的位置。它应该是这样的:

MERGE INTO
   Students AS T
USING 
   (SELECT @id as cardid, @name as name, @DT as FirstEntry, @DT as LastEntry) AS S
ON
   (S.cardid = T.cardid
   AND
   S.name = T.name)
WHEN MATCHED THEN
   UPDATE SET LastEntry =  s.LastEntry
WHEN NOT MATCHED THEN
   INSERT (cardid,  name, FirstEntry, LastEntry) VALUES(s.cardid, s.name, s.FirstEntry, s.LastEntry )
OUTPUT $action, inserted.cardid,  inserted.name, inserted.FirstEntry, inserted.LastEntry;

修改

您的output子句应该使用inserted.<col_name>而不是S.<col_name>来返回列名,以查看新插入或更新的值。如果要在更新之前查看值,也可以使用deleted.<col_name>(对于插入,将null。)