我的格式为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)的表:
使用TSQL,我想将XML更新为:
<Books>
<Book>
<Name>1</Name>
</Book>
<Book>
<Name>2</Name>
</Book>
<Book>
<Name>3</Name>
</Book>
</Books>
同样,我需要查找'lookup'表并将节点的值更新为ID而不是名称。
我能想到这样做的唯一方法是创建一个循环并使用XPath提取名称,查询查找表,然后使用'replace value of'调用XML上的modify。有没有更好的方法,因为我认为我提出的解决方案会非常慢?解决方案需要在TSQL中,并且在调用SP之前无法在业务逻辑中执行。我想有一种方法可以在基于集合的操作中执行此操作,但我很难找到它。
答案 0 :(得分: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
答案 1 :(得分: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