Stored-Procedures

如何在 SQL 2008 中使用帶有 XML 參數的儲存過程更新表?

  • January 21, 2015

我有以下儲存過程查詢。此查詢不完整。我需要幫助來完成此查詢。

問題:

在這個 SP 中,我在 SP 中接收到格式正確的 XML 字元串。我的目標是更新 Notes 表中與 XML 中傳遞的 Notes 匹配的 NoteId 的那些行。

例如:如果 XML 有兩個 NoteId = 1、2 的註釋,並且表有三個 NoteId = 1、2、3 的註釋,我想為 NoteId = 1、2 的行更新表的 NoteText。請幫我完成我的儲存過程。

輸入 XML:

<Notes>   
 <Note>
   <NoteId>1</NoteId>
   <NoteText>Hello</NoteText>    
 </Note> 
 <Note>
   <NoteId>2</NoteId>
   <NoteText>World</NoteText>    
 </Note> 
</Notes>

更新前的表格:

NoteId | NoteText | IsDeleted   
1        Hell       0
2        Worl       0
3        Test       0   

更新後的表需要如下所示:

NoteId | NoteText | IsDeleted   
1        Hello      0
2        World      0
3        Test       0  

這是我目前擁有的儲存過程:

ALTER PROCEDURE USP_Notes_UpsertNotes 
   (@notesToUpsert XML)
AS
BEGIN

   SET NOCOUNT ON;

       UPDATE Notes
       SET NoteText = n.note_text
       FROM (  select  T.C.value('(NoteId/text())[1]','varchar(500)') as note_id,
                       T.C.value('(NoteText/text())[1]','varchar(500)') as note_text **PROBLEM**
               from @notesToUpsert.nodes('/Notes/Note') as T(C) 
            )   as n

       WHERE n.note_id = Notes.NoteId AND Notes.IsDeleted = 0

END
GO

錯誤截圖:

錯誤資訊

.nodes() 方法必須從 xml 的根目錄開始。然後它將為每個匹配節點返回一個“行”以供SELECT子句處理。它應該如下所示:

from @notesToUpsert.nodes('/Notes/Note') as note(col)

(順便說一句,使用“note”作為別名令人困惑。也許 T(c) 更容易調試?)

然後子句中的 XQuery 在SELECT每個“行”(即一個<Note>元素)的 xml 上下文中執行。查詢路徑將是:

col.value('(./Text)[1]','varchar(500)')

,col.value('(/Notes/Note/Text)[1]','varchar(500)')

一個方便的調試幫助是只為每個“行”轉儲 xml:

select
   col.query('.') as Debug
...

編輯:根據 Mikael 的評論重新測試。我無法重現我之前的輸出並刪除了有問題的行。

引用自:https://dba.stackexchange.com/questions/89428