0

私は次の形式のXMLを持っています:

<Books>
    <Book>
        <Name>Lord of the Rings</Name>
    </Book>
    <Book>
        <Name>Harry Potter</Name>
    </Book>
    <Book>
        <Name>Girl with the Dragon Tattoo</Name>
    </Book> 
</Books>

次に、2つの列(IdとName)を含むテーブルがあります。

  • 1:ロードオブザリング
  • 2:ハリーポッター
  • 3:ドラゴン・タトゥーの女

TSQLを使用して、XMLを次のように更新したいと思います。

<Books>
    <Book>
        <Name>1</Name>
    </Book>
    <Book>
        <Name>2</Name>
    </Book>
    <Book>
        <Name>3</Name>
    </Book> 
</Books>

のように、「ルックアップ」テーブルをルックアップし、ノードの値を名前ではなくIDに更新する必要があります。

これを行うために私が考えることができる唯一の方法は、ループを作成し、XPathを使用して名前を抽出し、ルックアップテーブルをクエリしてから、「replacevalueof」を使用してXMLでmodifyを呼び出すことです。私の提案した解決策が非常に遅くなると私が想像するので、より良い方法はありますか?ソリューションはTSQLである必要があり、SPを呼び出す前にビジネスロジックで実行することはできません。セットベースの操作でこれを行う方法があると思いますが、私はそれを見つけるのに苦労しています。

4

2 に答える 2

1

私はあなたが正しい道を進んでいると思います。個人的には遅くなるとは思いません。それとも他の方法で見つけましたか?

MSDN@http://msdn.microsoft.com/en-us/library/ms190675.aspxからのこの例を検討してください

DECLARE @myDoc xml
SET @myDoc = '<Root>
<Location LocationID="10" 
            LaborHours=".1"
            MachineHours=".2" >Manu steps are described here.
<step>Manufacturing step 1 at this work center</step>
<step>Manufacturing step 2 at this work center</step>
</Location>
</Root>'
--SELECT @myDoc

ここでこれは非常に迅速な操作だと思います。

SET @myDoc.modify('
  replace value of (/Root/Location[1]/@LaborHours)[1]
  with (
       if (count(/Root/Location[1]/step) > 3) then
         "3.0"
       else
          "1.0"
      )
')
SELECT @myDoc
于 2012-06-20T15:02:35.607 に答える
0

これは洗練された解決策ではないと思いますが、この質問を表示している他の人を助けるための答えがあることを確認するために、これが私の解決策でした。

DECLARE @BookId NVARCHAR(10)
DECLARE @BookName NVARCHAR(100)
DECLARE @Counter INT
DECLARE @MaxCounter INT
SET @Counter = 1

SET @MaxCounter = @BooksXml.value('count(/Books/Book)', 'int')

WHILE @Counter <= @MaxCounter
BEGIN
    SET @BookName = @BooksXml.value('(/Books/Book[sql:variable("@Counter")]/Name/text())[1]', 'nvarchar(100)')
    SELECT @BookId=CAST(ProductID AS NVARCHAR(10)) FROM Book WHERE Name = @BookName

    SET @BooksXml.modify('replace value of (/Books/Book[sql:variable("@Counter")]/Name/text())[1] with sql:variable("@BookId")')

    SET @Counter = @Counter + 1
END
于 2012-06-22T11:27:18.427 に答える