简体   繁体   English

使用 CROSS APPLY 从 XML 到 MSSQL 的数据

[英]Data from XML to MSSQL using CROSS APPLY

I'm having trouble extracting some data from a XML file to MSSQL DB using CROSS APPLY, here is what I have:我无法使用 CROSS APPLY 从 XML 文件中提取一些数据到 MSSQL DB,这就是我所拥有的:

Note: I did read about how to post here but pardon me if I'm still wrong.注意:我确实读过如何在这里发帖,但如果我仍然错了,请原谅我。

XML File: XML 文件:

<?xml version="1.0" encoding="UTF-8" ?>
<ZMPROD01>
   <IDOC BEGIN="1">
      <EDI_DC40 SEGMENT="1">
         <TABNAM>EDI_DC40</TABNAM>
         <DOCNUM>0000003899888135</DOCNUM>
         <CREDAT>20220201</CREDAT>
         <CRETIM>152041</CRETIM>
      </EDI_DC40>
      <ZPROD SEGMENT="1">
         <WERKS>8285</WERKS>
         <LGNUM>0</LGNUM>
         <AUFNR>000915229446</AUFNR>
         <LINENO>RM01PL01</LINENO>
         <CHARG>0006186588</CHARG>
         <START1>20220202</START1>
         <START2>211609</START2>
         <QTY>4166.000</QTY>
         <END1>20220202</END1>
         <END2>240000</END2>
         <MAKTX>579 FUS5 75ML ULTRA SENST GEL</MAKTX>
         <PLN_ORDER>6963701111</PLN_ORDER>
         <Z1PRODI SEGMENT="1">
            <POSNR>000010</POSNR>
            <MATNR>000000000098920665</MATNR>
         </Z1PRODI>
         <Z1PRODI SEGMENT="1">
            <POSNR>000040</POSNR>
            <HRKFT>V010</HRKFT>
         </Z1PRODI>
         <Z1PRODI SEGMENT="1">
            <POSNR>000050</POSNR>
            <MATNR>000000000099396964</MATNR>
         </Z1PRODI>
      </ZPROD>
   </IDOC>
</ZMPROD01>

My SQL query:我的 SQL 查询:

INSERT INTO XMLTESTTABLE(PONo, ASP, LOTNo, EntryDate, StartDate, EndDate, GAS, PlannedQty, LineNum, SAPDesc, StartTime, EndTime)
SELECT
   MY_XML.ZPROD.query('AUFNR').value('.', 'VARCHAR(9)'),
   MY_XML.ZPROD.query('CHARG').value('.', 'VARCHAR(8)'),
   MY_XML.ZPROD.query('PLN_ORDER').value('.', 'VARCHAR(10)'),
   MY_XML.ZPROD.query('START1').value('.', 'date'),
   MY_XML.ZPROD.query('START1').value('.', 'date'),
   MY_XML.ZPROD.query('END1').value('.', 'date'),
   MY_XML.ZPROD.query('CHARG').value('.', 'VARCHAR(8)'),
   MY_XML.ZPROD.query('QTY').value('.', 'VARCHAR(9)'),
   MY_XML.ZPROD.query('LINENO').value('.', 'VARCHAR(1)'),
   MY_XML.ZPROD.query('MAKTX').value('.', 'VARCHAR(9)'),
   MY_XML.ZPROD.query('START2').value('.', 'time'),
   MY_XML.ZPROD.query('END2').value('.', 'time')
FROM (SELECT CAST(MY_XML AS xml)
      FROM OPENROWSET(BULK 'C:\Users\PC_user\Documents\Idoc3899888135.xml', SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
      CROSS APPLY MY_XML.nodes('ZMPROD01/ZPROD') AS MY_XML (ZPROD);

The result I get is (0 rows affected).我得到的结果是(0 行受影响)。 I tried replacing ZMPROD01/ZPROD several times but different errors appeared, at some point complained about being unable to convert to date datatype.我尝试多次更换 ZMPROD01/ZPROD,但出现了不同的错误,有时抱怨无法转换为日期数据类型。

On a separate note how, can I get data from EDI_DC40 as well?在单独的说明中,我也可以从 EDI_DC40 获取数据吗? Not sure how the CROSS APPLY would look like to look for different places on the document.不确定 CROSS APPLY 在文档上查找不同位置时的外观。

Your help is appreciated.感谢您的帮助。

Thanks.谢谢。

Please try the following solution.请尝试以下解决方案。

Notable points:值得注意的点:

  • I adjusted the XPath expression in the .nodes() method.我在.nodes()方法中调整了 XPath 表达式。
  • No need to use the .query() method.无需使用.query()方法。
  • text() is added for performance reasons.出于性能原因添加了text()
  • Last two data elements converted into TIME data type.最后两个数据元素转换为TIME数据类型。
  • As it was already mentioned, the <END2>240000</END2> is not a legit value for the TIME data type.正如已经提到的, <END2>240000</END2>不是TIME数据类型的合法值。

SQL SQL

--INSERT INTO XMLTESTTABLE(PONo, ASP, LOTNo, EntryDate, StartDate, EndDate, GAS, PlannedQty, LineNum, SAPDesc, StartTime, EndTime)
SELECT ZPROD.value('(AUFNR/text())[1]', 'VARCHAR(9)')
    , ZPROD.value('(CHARG/text())[1]', 'VARCHAR(8)')
    , ZPROD.value('(PLN_ORDER/text())[1]', 'VARCHAR(10)')
    , ZPROD.value('(START1/text())[1]', 'date')
    , ZPROD.value('(START1/text())[1]', 'date')
    , ZPROD.value('(END1/text())[1]', 'date')
    , ZPROD.value('(CHARG/text())[1]', 'VARCHAR(8)')
    , ZPROD.value('(QTY/text())[1]', 'VARCHAR(9)')
    , ZPROD.value('(LINENO/text())[1]', 'VARCHAR(1)')
    , ZPROD.value('(MAKTX/text())[1]', 'VARCHAR(9)')
    , TRY_CAST(STUFF(STUFF(ZPROD.value('(START2/text())[1]', 'CHAR(6)'),3,0,':'),6,0,':') AS TIME)
    , TRY_CAST(STUFF(STUFF(ZPROD.value('(END2/text())[1]', 'CHAR(6)'),3,0,':'),6,0,':') AS TIME)
FROM (SELECT CAST(MY_XML AS xml)
      FROM OPENROWSET(BULK 'e:\Temp\Idoc3899888135.xml', SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
      CROSS APPLY MY_XML.nodes('/ZMPROD01/IDOC/ZPROD') AS MY_XML (ZPROD);

Your path seems wrong - what about:你的路径似乎是错误的 - 怎么样:

CROSS APPLY MY_XML.nodes('ZMPROD01/IDOC/ZPROD') AS MY_XML (ZPROD);

You seem to have forgotten the IDOC你好像忘记了IDOC

And the data type is because you cannot convert the times to the data type time.数据类型是因为您无法将时间转换为数据类型时间。 Try starting with the select where everything is converted to varchar, then start changing the data tyoes, and you will find the errors尝试从 select 开始,将所有内容都转换为 varchar,然后开始更改数据类型,您会发现错误

SELECT CAST('211609' AS TIME)

returns error返回错误

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM