如何在sql查询中粉碎提到的XML

时间:2016-03-07 10:47:40

标签: xml sql-server-2008

我想以这种方式使用节点(' / Nodes1')在SQL查询中粉碎下面的xml,这样结果应该是表中的2条记录。目前,我正在两次读取xml节点(分别用于ChildNode2和ChildNode3)并将数据插入表中。

ChildNode1   Test
 01234        Test1
 01234        Test2

XML如下所示:

<Node1>
 <ChildNode1>01234</ChildNode1> 
 <ChildNode2>Test1</ChildNode2>
 <ChildNode3>Test2</ChildNode3>
</Node1> 

编辑:实际的XML是:

 <DEBMAS06>
  <IDOC BEGIN="1">    
    <E1KNA1M SEGMENT="1">
     <MSGFN>005</MSGFN>
     <KUNNR>0000000675</KUNNR>
     <BBBNR>0000000</BBBNR>
     <BBSNR>00000</BBSNR>
     <BEGRU>0001</BEGRU>
     <BRSCH>9000</BRSCH>
     <BUBKZ>0</BUBKZ>
     <KTOKD>0001</KTOKD>
     <KUKLA>SC</KUKLA>
     <LAND1></LAND1>
     <NAME1></NAME1>
     <NAME4></NAME4>
     <ORT01></ORT01>
     <SORTL></SORTL>
     <SPRAS>E</SPRAS>
     <STRAS>,</STRAS>
     <TELF1>25950393</TELF1>
     <TELFX>25588160</TELFX>
     <LZONE>0000000001</LZONE>
     <GFORM>06</GFORM>
     <BRAN1>TRAD</BRAN1>
     <BRAN2>TRADINGCO</BRAN2>
     <BRAN3>TRADINGCO</BRAN3>
     <BRAN4>TRAD</BRAN4>
     <UMJAH>0000</UMJAH>
     <JMZAH>000000</JMZAH>
     <JMJAH>0000</JMJAH>
     <UMSA1>0</UMSA1>
     <HZUOR>00</HZUOR>
     <SPRAS_ISO>EN</SPRAS_ISO>
     <E1KNA11 SEGMENT="1">
     <RGDATE>00000000</RGDATE>
     <RIC>00000000000</RIC>
     <RNEDATE>00000000</RNEDATE>
     <LEGALNAT>0000</LEGALNAT>
    </E1KNA11>      
   </E1KNA1M>
  </IDOC>
 </DEBMAS06> 

我的查询:

SELECT ct1.n.value('KUNNR[1]','NVARCHAR(10)')+ct2.n.value('.','NVARCHAR(10)') AS IDOCID 
FROM @xmlStringOrig.nodes('DEBMAS06/IDOC/E1KNA1M') AS ct1(n)
     CROSS APPLY ct1.n.nodes('/*[local-name()="BRAN1" OR local-name()="BRAN3"]') AS ct2(n) 

但是上面的查询给出了一个错误:

  

XQuery [ct1.n.nodes()]:在XQuery表达式结束时不再需要令牌。发现&#39; OR&#39;

预期结果应如下:

IDOCID
0000000675TRAD
0000000675TRADINGCO

2 个答案:

答案 0 :(得分:1)

EDIT2

这应该是您的查询:

SELECT ct1.n.value('KUNNR[1]','NVARCHAR(10)')+ct2.n.value('.','NVARCHAR(10)') AS IDOCID 
FROM @xmlStringOrig.nodes('/DEBMAS06/IDOC/E1KNA1M') AS ct1(n)
     CROSS APPLY ct1.n.nodes('*[local-name()="BRAN1" or local-name()="BRAN3"]') AS ct2(n)

我必须承认我不明白你想要达到的目标。一般逻辑如何知道你想要什么以及如何解释这些价值观?

这很有效,但很难看......

DECLARE @x XML=
'<Node1>
 <ChildNode1>01234</ChildNode1> 
 <ChildNode2>Test1</ChildNode2>
 <ChildNode3>Test2</ChildNode3>
</Node1>';

SELECT @x.value('(/Node1/ChildNode1)[1]','varchar(15)') AS NumericValue
      ,@x.value('(/Node1/ChildNode2)[1]','varchar(15)') AS TestCaption
UNION ALL
SELECT @x.value('(/Node1/ChildNode1)[1]','varchar(15)')
      ,@x.value('(/Node1/ChildNode3)[1]','varchar(15)');

结果

NumericValue    TestCaption
01234           Test1
01234           Test2

编辑:更多方法:

WITH TwoRows(RowInx) AS (SELECT 1 UNION ALL SELECT 2)
SELECT @x.value('(/Node1/ChildNode1)[1]','varchar(15)') AS NumericValue
      ,CASE WHEN RowInx=1 
            THEN @x.value('(/Node1/ChildNode2)[1]','varchar(15)') 
            ELSE @x.value('(/Node1/ChildNode3)[1]','varchar(15)') END AS TestCaption
FROM TwoRows;

SELECT @x.value('(/Node1/ChildNode1)[1]','varchar(15)') AS NumericValue
      ,Two.Children.value('.','varchar(15)') AS TestCaption
FROM @x.nodes('/Node1/*[local-name()="ChildNode2" or local-name()="ChildNode3"]') AS Two(Children)

答案 1 :(得分:1)

这会选择我认为你想要的东西:

xml:

DECLARE @x XML=
'<DEBMAS06>
  <IDOC BEGIN="1">    
    <E1KNA1M SEGMENT="1">
     <MSGFN>005</MSGFN>
     <KUNNR>0000000675</KUNNR>
     <BBBNR>0000000</BBBNR>
     <BBSNR>00000</BBSNR>
     <BEGRU>0001</BEGRU>
     <BRSCH>9000</BRSCH>
     <BUBKZ>0</BUBKZ>
     <KTOKD>0001</KTOKD>
     <KUKLA>SC</KUKLA>
     <LAND1></LAND1>
     <NAME1></NAME1>
     <NAME4></NAME4>
     <ORT01></ORT01>
     <SORTL></SORTL>
     <SPRAS>E</SPRAS>
     <STRAS>,</STRAS>
     <TELF1>25950393</TELF1>
     <TELFX>25588160</TELFX>
     <LZONE>0000000001</LZONE>
     <GFORM>06</GFORM>
     <BRAN1>TRAD</BRAN1>
     <BRAN2>TRADINGCO</BRAN2>
     <BRAN3>TRADINGCO</BRAN3>
     <BRAN4>TRAD</BRAN4>
     <UMJAH>0000</UMJAH>
     <JMZAH>000000</JMZAH>
     <JMJAH>0000</JMJAH>
     <UMSA1>0</UMSA1>
     <HZUOR>00</HZUOR>
     <SPRAS_ISO>EN</SPRAS_ISO>
     <E1KNA11 SEGMENT="1">
     <RGDATE>00000000</RGDATE>
     <RIC>00000000000</RIC>
     <RNEDATE>00000000</RNEDATE>
     <LEGALNAT>0000</LEGALNAT>
    </E1KNA11>      
   </E1KNA1M>
  </IDOC>
 </DEBMAS06>';

查询:

;WITH x AS (
    SELECT 
        kunnr=n.v.value('(KUNNR)[1]','NVARCHAR(10)'),
        bran1=n.v.value('(BRAN1)[1]','NVARCHAR(10)'),
        bran3=n.v.value('(BRAN3)[1]','NVARCHAR(10)')
    FROM 
        @x.nodes('DEBMAS06/IDOC/E1KNA1M') AS n(v)
)
SELECT result=kunnr+bran1 FROM x
UNION ALL
SELECT result=kunnr+bran3 FROM x;

如果您认为需要忽略名称空间(我不会从XML中看到原因),例如bran1=n.v.value('(BRAN1)[1]','NVARCHAR(10)'),将成为bran1=n.v.value('*[local-name()="BRAN1"][1]','NVARCHAR(10)'),

结果:

+---------------------+
|       result        |
+---------------------+
| 0000000675TRAD      |
| 0000000675TRADINGCO |
+---------------------+