Sql server SQL Server检索所有值
我有一个表,我们称之为Sql server SQL Server检索所有值,sql-server,xml,nodes,cross-apply,Sql Server,Xml,Nodes,Cross Apply,我有一个表,我们称之为TBL,其中一列的类型为XML XML列(此处称为XML)的格式如下: <START xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="87jjhanM"> <Header xmlns=""> ... </Header> <Fetch xml
TBL
,其中一列的类型为XML
XML
列(此处称为XML
)的格式如下:
<START xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="87jjhanM">
<Header xmlns="">
...
</Header>
<Fetch xmlns="">
.....
</Fetch>
<Send xmlns="">
<Supplier>
<Deals>
<Deal>
<Field1> </Field1>
<Field2> </Field2>
</Deal>
</Deals>
</Supplier>
<Supplier>
<Deals>
<Deal>
<Field1> </Field1>
<Field2> </Field2>
</Deal>
</Deals>
</Supplier>
</Send>
</START>
据我所知,它只是在每个/Start/Send/
下查找第一个值/Supplier/Deals/Deals/Field1
,但它不起作用-它只返回受影响的0行(我知道我应该说的XML文件中存在特定的结构)
我相信这很容易,但我就是不明白为什么上面的方法不起作用。非常感谢您的帮助。有很多错误可能与您的问题没有直接关系:XML是区分大小写的(所以
START
,而不是START
),外部元素位于名称空间(87jhanm
),因此需要使用和XMLNAMESPACES
,诸如此类。但假设我们能解决这些问题:
WITH XMLNAMESPACES ('87jjhanM' AS n)
SELECT
A.value('Field1[1]', 'VARCHAR(100)') AS Field1,
A.value('Field2[1]', 'VARCHAR(100)') AS Field2
FROM TBL
CROSS APPLY [xml].nodes('/n:START/Send/Supplier/Deals/Deal') x(A);
理想情况下,交叉应用
应该在我们感兴趣的最低重复元素上进行(Deal
,在本例中),以使值
查询尽可能简单,但这不是一个硬性要求
相反,如果希望所有值都位于字段1
和字段2
中,但不关心它们实际位于哪个字段中,则可以按名称进行匹配:
WITH XMLNAMESPACES ('87jjhanM' AS n)
SELECT
A.value('.', 'VARCHAR(100)') AS [Field]
FROM TBL
CROSS APPLY [xml].nodes('/n:START/Send/Supplier/Deals/Deal/*[local-name()="Field1" or local-name()="Field2"]') x(A);
如果您想,比如说,从
字段开始获取每个元素中的所有内容
。。。好吧,然后事情变得更烦人了,但幸运的是,您说您知道所涉及的XML的结构,所以这不应该是一个问题。您尝试为brevety缩短并清理这个,这很好。但是-至少我这么认为-你做了一点太多
Jeroen Mostert已经指出了大小写(“START”!=“START”)和名称空间。在第一行中有一个(相当奇怪的)defualt名称空间,有些名称空间您根本不用
XML中重复的xmlns=”“
非常危险。这可能是由T-SQL
命令和forxml
和子选择创建的。重点是:这不仅仅是一个愚蠢的忽略,而是为内部元素定义了一个新的默认名称空间。这就是为什么我使用了名称空间通配符*:
,并省略了名称空间声明
我向每个级别添加了一些额外的元素,并假设在
下面可以有1:n
和1:n
节点(至少命名指向此)。为此,您可以使用两个级别的外部/交叉应用
:
DECLARE @mockupTBL TABLE(ID INT IDENTITY, TheXml XML);
INSERT INTO @mockupTBL VALUES
(N'<START xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="87jjhanM">
<Header xmlns="">
<SomeNodeWithinHeader SomeValue="blah"/>
</Header>
<Fetch xmlns="">
<SomeNodeWithinFetch SomeValue="blubb"/>
</Fetch>
<Send xmlns="">
<Supplier>
<SupplierRelatedData value="Sup1"/>
<Deals>
<Deal>
<Field1>A1</Field1>
<Field2>A2</Field2>
</Deal>
<Deal>
<Field1>A3</Field1>
<Field2>A4</Field2>
</Deal>
</Deals>
</Supplier>
<Supplier>
<SupplierRelatedData value="Sup2"/>
<Deals>
<Deal>
<Field1>B1</Field1>
<Field2>B2</Field2>
</Deal>
</Deals>
</Supplier>
</Send>
</START>');
SELECT m.TheXml.value(N'(/*:START/Header/SomeNodeWithinHeader/@SomeValue)[1]',N'nvarchar(max)') ValueWithinHeader
,m.TheXml.value(N'(/*:START/Fetch/SomeNodeWithinFetch/@SomeValue)[1]',N'nvarchar(max)') ValueWithinFetch
,sup.value(N'(SupplierRelatedData/@value)[1]',N'nvarchar(max)') SupplierRelatedData
,deal.value(N'(Field1/text())[1]',N'nvarchar(max)') AS Field1
,deal.value(N'(Field2/text())[1]',N'nvarchar(max)') AS Field2
FROM @mockupTBL AS m
OUTER APPLY m.TheXml.nodes(N'/*:START/Send/Supplier') AS A(sup)
OUTER APPLY A.sup.nodes(N'Deals/Deal') AS B(deal)
DECLARE @mockupTBL TABLE(ID INT IDENTITY, TheXml XML);
INSERT INTO @mockupTBL VALUES
(N'<START xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="87jjhanM">
<Header xmlns="">
<SomeNodeWithinHeader SomeValue="blah"/>
</Header>
<Fetch xmlns="">
<SomeNodeWithinFetch SomeValue="blubb"/>
</Fetch>
<Send xmlns="">
<Supplier>
<SupplierRelatedData value="Sup1"/>
<Deals>
<Deal>
<Field1>A1</Field1>
<Field2>A2</Field2>
</Deal>
<Deal>
<Field1>A3</Field1>
<Field2>A4</Field2>
</Deal>
</Deals>
</Supplier>
<Supplier>
<SupplierRelatedData value="Sup2"/>
<Deals>
<Deal>
<Field1>B1</Field1>
<Field2>B2</Field2>
</Deal>
</Deals>
</Supplier>
</Send>
</START>');
SELECT m.TheXml.value(N'(/*:START/Header/SomeNodeWithinHeader/@SomeValue)[1]',N'nvarchar(max)') ValueWithinHeader
,m.TheXml.value(N'(/*:START/Fetch/SomeNodeWithinFetch/@SomeValue)[1]',N'nvarchar(max)') ValueWithinFetch
,sup.value(N'(SupplierRelatedData/@value)[1]',N'nvarchar(max)') SupplierRelatedData
,deal.value(N'(Field1/text())[1]',N'nvarchar(max)') AS Field1
,deal.value(N'(Field2/text())[1]',N'nvarchar(max)') AS Field2
FROM @mockupTBL AS m
OUTER APPLY m.TheXml.nodes(N'/*:START/Send/Supplier') AS A(sup)
OUTER APPLY A.sup.nodes(N'Deals/Deal') AS B(deal)
blah blubb Sup1 A1 A2
blah blubb Sup1 A3 A4
blah blubb Sup2 B1 B2