且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用SQL Server在XQuery上动态获取XML文档的第二个或第三个元素

更新时间:2023-02-06 18:23:07

好的,再次感谢你J Snooze,对不起,我无法跟进这个及时。你的最后一个回应似乎让我们走上了正确的轨道,但幸运的是,对于我需要的东西有一个更简单的答案,这是一个语法问题,一开始我尝试了几种语法,但我找不到它,这就是为什么我做了问题。



我能够在表的伪XML字段和CAST到XML上有效地使用它,类似于:

   -   假设您有多个ProductDescription项目 

DECLARE @ Index int
DECLARE @ myDoc VARCHAR ( max)

SET @ Index = 2
SET @myDoc = ' < root>
< productdescription productid =9865productname =Road Bike>
< country> China< / country>
.....'

- 提取子元素Country来自第二个元素(上面是@Index = 2)
SELECT CAST( @ myDoc AS XML).value(' (/ Root) / ProductDescription)[sql:variable(@ Index)] / Country [1]'' VARCHAR(20)'

- 提取属性ProductId第二个元素(@Index = 2)
SELECT CAST( @ myDoc AS XML).value(' (/ Root) / ProductDescription / @ ProductID)[sql:variable(@ Index)] [1]'' int'

< / productdescription>< / root>


How to get the second or third element DYNAMICALLY of a XML document on XQuery with SQL Server, specifically using the .value method.

By dynamically I mean that I can use a SQL SERVER variable like

DECLARE @Index int

with some sort of syntax within the first parameter of the .value method , because if you just use a VARCHAR variable, for example, you get an error like :

The argument 1 of the XML data type method "value" must be a string literal

This is in Sql server 2008.

I havent found answer to this on internet, or maybe I dont know how to question, but there's only samples to access the first element or the second and so on but hardcoding.

I've seen a similar syntax like the following but with the .exists method.
(and this is what I would like to do)

-- This is clearly an example of MSDN

DECLARE @Index int
DECLARE @myDoc xml

SET @Index = 3
SET @myDoc = '<Root>
                <ProductDescription ProductID="9865" ProductName="Road Bike"> 
                        .....'

SELECT  @myDoc.value('(/Root/ProductDescription/@ProductID)[ =sql:variable("@Index") ]', 'int' )



Unfortunately this produces the error : XQuery [value()]: Syntax error near '='

Context :
I have a process that needs to execute actions based on the values of the second or third element.
There is no possibility to change the field in database or the way the XML is structured.

Ok, thank you again J Snooze, I'm sorry I couldnt follow up on this timely. Your last response it seems to put us on the right track, but fortunately there was a simpler answer for what I need and it was a matter of syntax, at the beginning I tried several syntax but I couldnt find it, that's why I made the question.

I was able to use this effectively on a pseudo XML field of a table and with CAST to XML, similar to this :
-- Suppose you have several ProductDescription items

DECLARE @Index int
DECLARE @myDoc VARCHAR(max)
 
SET @Index = 2
SET @myDoc = '<root>
                <productdescription productid="9865" productname="Road Bike"> 
                     <country>China</country>
                        .....'
-- Extracts the subelement "Country" from the second element (above @Index = 2)
SELECT  CAST(@myDoc AS XML).value('(/Root/ProductDescription)[sql:variable("@Index")]/Country[1]', 'VARCHAR(20)' )
 
-- Extracts the atribute "ProductId" of the second element (above @Index = 2)
SELECT  CAST(@myDoc AS XML).value('(/Root/ProductDescription/@ProductID)[sql:variable("@Index")][1]', 'int' )

</productdescription></root>