2011-06-28 9 views
1

私は次の2つのテスト/サンプルクエリを使用して、XMLからSQL 2008テーブルにデータをINSERTおよびUPDATEします。実際には、入ってくるXML構造がSQLテーブルのものにマッチするという事実のかなり基本的なものです(もちろん、もちろん更新には必要なフィールドのみがあります)。 UPDATE文の上に今複数のXMLレコードをSQL 2008に挿入して更新する - 解決策はありますが、正しいものではないでしょうか?

INSERT文

declare @passedXML xml 
set @passedXML='<root><record><name>Sam</name><age>37</age><comments /></record><record><name>Dan</name><age>32</age><comments /></record></root>' 

insert into test (name, age, comments) 
select x.record.query('name').value('.', 'varchar(255)'), 
     x.record.query('age').value('.', 'int'), 
     x.record.query('comments').value('.','varchar(255)') 
from @passedXML.nodes('root/record') as x(record) 

だから我々がする必要があるとして、そこには問題は、2つのXML "レコードは" 挿入されません取得... :

UPDATE文

declare @passedXML xml 
set @passedXML='<root><record><id>3</id><comments>This is a new comment</comments></record><record><id>2</id><comments>Michael Michael</comments></record></root>' 
update test 
set comments = (select x.record.query('comments').value('.','varchar(255)') 
    from @passedXML.nodes('root/record') as x(record) 
    where id = x.record.query('id').value('.','bigint')) 

いいえ、アップデートが動作します - 2つのXML "レコード"には、渡された内容に基づいてコメントフィールドが更新されます

と言うなら、私の質問は(UPDATEが実行されたときに、クエリが100を言う句はXMLではなくTESTテーブルからです..上記のサンプルUPDATE与えもちろん

ISどのくらいのレコードがテーブルTESTにあるか)レコードが更新されました..もちろん、2つのレコード(この場合)のみが更新されましたが、SQLはテーブル全体を実行する必要がありましたか? 私は、XMLがどこから来ているTESTテーブルにどこかにwhere節を持たせる方法があると思いますか?すなわち、TESTを更新された項目だけに制限するか?

+0

あなたのプログラミング言語はC#のでしょうか? – Pankaj

答えて

2

私は少しあなたの更新クエリに変更してみましょう:

declare @passedXML xml 
set @passedXML='<root><record><name>Sam</name><age>37</age><comments /></record><record><name>Dan</name><age>32</age><comments /></record></root>' 

DECLARe @test TABLE (id bigint IDENTITY(1,1),name nvarchar(100), age int, comments varchar(255)) 
insert into @test (name, age, comments) 
select x.record.query('name').value('.', 'varchar(255)'), 
     x.record.query('age').value('.', 'int'), 
     x.record.query('comments').value('.','varchar(255)') 
from @passedXML.nodes('root/record') as x(record) 


set @passedXML='<root><record><id>99999</id><comments>This is a new comment</comments></record><record><id>2</id><comments>Michael Michael</comments></record></root>' 
; with CTE as( 
SELECT x.record.query('comments').value('.','varchar(255)') comment, 
     x.record.query('id').value('.','int') id 
    from @passedXML.nodes('root/record') as x(record)) 
update @test 
set comments = cte.comment 
FROM @test T 
JOIN CTE oN cte.id=t.id 

更新結果を:(1 row(s) affected)

SQLサーバーは、すべての行を更新しないために十分スマートです。 あなたが実行計画を見れば、あなたはそのハッシュが一致した行の唯一の実際の数ではなく、2持って見ることができます。

enter image description here

を@@ ROWCOUNTもあなた1に表示され、それは大丈夫です。

すでに ごと行を更新、あなたの例では

(XMLでそのようなIDが存在しない場合は、NULLがコメントに挿入する必要があります)

+0

それは非常に涼しい..私はCTE声明を見たことがあるが、彼らが何であるかを本当に知ったことはないと認めなければならない。もちろん、統計情報も含めてくれてありがとう、完璧な例と感謝します。 –

関連する問題