Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server检索所有值_Sql Server_Xml_Nodes_Cross Apply - Fatal编程技术网

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