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>

然后我有一个包含两列(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 提取名称,查询查找表,然后使用“替换值”对 XML 调用修改。有没有更好的方法,因为我想我提出的解决方案会很慢?该解决方案需要在 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 回答