简体   繁体   English

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

[英]SQL Server Merge Upsert only doing Updates and no inserts

I want to record student movement when they swipe their cards on the door. 我想在他们在门上刷卡时记录学生的动作。 Every time a card id and name is presented, I want to check if its a new combination which is not already in the students table. 每次出现卡片ID和名称时,我想检查它是否是学生表中尚未存在的新组合。 If not present then insert a new record with FirstEntry and LastEntry being the same date and cardid and name being the one that is sent in to the respective parameters. 如果不存在,则插入一条新记录,其中FirstEntry和LastEntry是相同的日期,cardid和name是发送到相应参数的记录。 If combination already present then only update the [LastEntry] field. 如果已存在组合,则仅更新[LastEntry]字段。 At the moment my query is only updating existing records, which means only the [LastEntry] field gets updated. 目前我的查询只是更新现有记录,这意味着只有[LastEntry]字段得到更新。 For update this is normal. 对于更新,这是正常的。 However, it doesn't insert a new record for a new entry. 但是,它不会为新条目插入新记录。 CardID and Name are the composite primary keys here on the table. CardID和Name是表格中的复合主键。

  • I don't want to use the IF Exists(Select...) method for acheiving this. 我不想使用IF存在(选择...)方法来实现这一点。
  • I want to use MERGE only. 我只想使用MERGE。
  • This action is to be done on the same table without using any temp tables 此操作将在同一个表上完成,而不使用任何临时表
  • After performing the action I want to see the affected records in either the update or insert scenarios. 执行操作后,我想在更新或插入方案中查看受影响的记录。 Only the following fields to be shown [cardid, name, FirstEntry, LastEntry] and not the other fields in the table. 只显示以下字段[cardid,name,FirstEntry,LastEntry]而不是表中的其他字段。
  • The table has other columns which I don't want to show or return. 该表有其他列,我不想显示或返回。

Here is my statement which only does updates 这是我的声明,只做更新

            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;

Along with updates I want it to effect inserts as well for new records 除了更新,我希望它能够影响插入以及新记录

Your using clause shouldn't be querying the Students table. 您的using子句不应该查询Students表。 That's where you put the new values you want to insert or update. 这就是您要插入或更新新值的位置。 It should look like this: 它应该如下所示:

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;

EDIT 编辑

Your output clause should probably be using inserted.<col_name> instead of S.<col_name> for the returned column names to see the new inserted or updated values. 您的output子句可能应该使用inserted.<col_name>而不是S.<col_name>来返回列名,以查看新插入或更新的值。 You can also use deleted.<col_name> if you want to see the value before it got updated (will be null for inserts). 如果要在更新之前查看值,也可以使用deleted.<col_name> (对于插入将为null )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM