2015-09-25 58 views
1

我想記錄學生在門上刷卡時的動作。每次提供卡片ID和名稱時,我都想檢查它是否已經存在於學生表中的新組合。如果不存在,則使用FirstEntry和LastEntry插入一條新記錄,它們的日期和Cardid是相同的,並且名稱是發送到相應參數中的那個記錄。如果組合已經存在,則只更新[LastEntry]字段。目前我的查詢只更新現有記錄,這意味着只有[LastEntry]字段被更新。更新這是正常的。但是,它不會爲新條目插入新記錄。 CardID和Name是表格上的複合主鍵。SQL Server合併Upsert僅進行更新並且沒有插入

  • 我不想使用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

那麼,你的問題到底是什麼? – NickyvV

+0

你的選擇完全符合你的要求。如果帶有「@id,@ name」鍵的記錄不存在,則不會插入任何內容。 –

+0

更新了問題Nicky – user20358

回答

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)。

+0

我不應該在這裏獲取舊的最後一個條目,而不僅僅是我發送的值。我認爲在更新的情況下,我將能夠在更新發生之前獲得較舊的值。這是可行的嗎? – user20358

+1

你決定你想看到什麼。你可以使用'刪除。 '看到舊值(當然''插入''將是'null'),並且你可以使用'插入'。 '看到新的值,或兩者的組合(確保如果將兩者結合使用以避免輸出中含糊不清的列名) – sstan

+0

謝謝。這工作。 – user20358