SQL-Server XML-Bulk-导入和读取表数据

时间:2016-09-15 14:18:19

标签: sql-server xml tsql

我有以下问题:

对于XML-Import into SQL-Sever,我使用以下代码:

DROP TABLE XMLwithOpenXML

CREATE TABLE XMLwithOpenXML
(
Id INT IDENTITY PRIMARY KEY,
XMLData XML,
LoadedDateTime DATETIME
)

INSERT INTO XMLwithOpenXML(XMLData, LoadedDateTime)
SELECT CONVERT(XML, BulkColumn) AS BulkColumn, GETDATE() 
FROM OPENROWSET(BULK '\\WINSER1\\proALPHA\\templates_eBus\\Test.xml', SINGLE_BLOB) AS x;

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)

SELECT @XML = XMLData FROM XMLwithOpenXML

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML

工作正常。但是在XML中,我不知道该怎么做:

    <MIME_INFO>
        <MIME>
            <MIME_TYPE>image/jpeg</MIME_TYPE>
            <MIME_SOURCE>ube105252.jpg</MIME_SOURCE>
            <MIME_PURPOSE>normal</MIME_PURPOSE>
            <MIME_ORDER>1</MIME_ORDER>
        </MIME>
        <MIME>
            <MIME_TYPE>image/jpeg</MIME_TYPE>
            <MIME_SOURCE>bbd372670.jpg</MIME_SOURCE>
            <MIME_PURPOSE>logo</MIME_PURPOSE>
            <MIME_ORDER>2</MIME_ORDER>
        </MIME>
    </MIME_INFO>

我的用户需要<MIME>-Blocks。但它们的名字相同!

如何在2 <Mime>-Tags中获得这8行满足?重命名不是解决方案,因为XML有超过2.000.000行!

THX。

编辑16:20 这里是上面其余的代码。使用此标签,它可以正常工作:

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)

SELECT @XML = XMLData FROM XMLwithOpenXML

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML

SELECT  [SUPPLIER_AID]
       ,REFERENCE_FEATURE_SYSTEM_NAME
       ,REFERENCE_FEATURE_GROUP_ID


FROM OPENXML(@hDoc, 'BMECAT/T_NEW_CATALOG/ARTICLE')
--FROM OPENXML(@hDoc, 'BMECAT/T_NEW_CATALOG/ARTICLE/ARTICLE_ORDER_DETAILS')
--## Hier werden die gewünschten Columns deklariert.
WITH 
(
     SUPPLIER_AID [varchar](25) 'SUPPLIER_AID'
    ,REFERENCE_FEATURE_SYSTEM_NAME [varchar](25) 'REFERENCE_FEATURE_SYSTEM_NAME'
    ,REFERENCE_FEATURE_GROUP_ID [varchar](25) 'REFERENCE_FEATURE_GROUP_ID'

)

----------------------------- EDIT 16092016 / 08:14 ------------ -----------------

我仍然不了解您的代码,因为您不使用真正的表格&#34; XMLwithOpenXML&#34;。 Hier是XML中的一篇约20.000的文章:

<BMECAT>
    <T_NEW_CATALOG>
        <ARTICLE mode="new">
            <SUPPLIER_AID>9900026005</SUPPLIER_AID>
            <MIME_INFO>
                <MIME>
                    <MIME_TYPE>image/jpeg</MIME_TYPE>
                    <MIME_SOURCE>ube105252.jpg</MIME_SOURCE>
                    <MIME_PURPOSE>normal</MIME_PURPOSE>
                    <MIME_ORDER>1</MIME_ORDER>
                </MIME>
                <MIME>
                    <MIME_TYPE>image/jpeg</MIME_TYPE>
                    <MIME_SOURCE>bbd372670.jpg</MIME_SOURCE>
                    <MIME_PURPOSE>logo</MIME_PURPOSE>
                    <MIME_ORDER>2</MIME_ORDER>
                </MIME>
                <MIME>
                    <MIME_TYPE>image/jpeg</MIME_TYPE>
                    <MIME_SOURCE>ube305149.jpg</MIME_SOURCE>
                    <MIME_PURPOSE>logo</MIME_PURPOSE>
                    <MIME_ORDER>3</MIME_ORDER>
                </MIME>
                <MIME>
                    <MIME_TYPE>image/jpeg</MIME_TYPE>
                    <MIME_SOURCE>ube108453.jpg</MIME_SOURCE>
                    <MIME_PURPOSE>others</MIME_PURPOSE>
                    <MIME_ORDER>4</MIME_ORDER>
                </MIME>
                <MIME>
                    <MIME_TYPE>application/pdf</MIME_TYPE>
                    <MIME_SOURCE>ube007100.pdf</MIME_SOURCE>
                    <MIME_PURPOSE>others</MIME_PURPOSE>
                    <MIME_ORDER>5</MIME_ORDER>
                </MIME>
            </MIME_INFO>
        </ARTICLE>
    </T_NEW_CATALOG>
</BMECAT>

您看到有一个SUPPLIER_AID和四个<MIME> - 标记。我只需要第一个和第二个(正常和徽标)。在这种情况下SUPPLIER_AID是什么?我认为代码必须如下:

WITH Numbered AS
(
    SELECT LoadedDateTime
          ,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS ID
          --,a.query('.') AS SUPPLIER_AID
          ,m.query('.') AS mime
    FROM XMLwithOpenXML AS t
    CROSS APPLY t.XMLData.nodes('BMECAT/T_NEW_CATALOG/ARTICLE/MIME_INFO/MIME') AS A(m)
)
SELECT ID
  --,[SUPPLIER_AID].value('(ARTICLE)[1]','nvarchar(max)') AS SUPPLIER_AID
    ,mime.value('(MIME/MIME_TYPE)[1]','nvarchar(max)') AS MIME_TYPE
    ,mime.value('(MIME/MIME_SOURCE)[1]','nvarchar(max)') AS MIME_SOURCE
    ,mime.value('(MIME/MIME_PURPOSE)[1]','nvarchar(max)') AS MIME_PURPOSE
    ,mime.value('(MIME/MIME_ORDER)[1]','nvarchar(max)') AS MIME_ORDER
FROM Numbered

使用新代码,我明白了:

+-----------+--------------+-------------+-----------+
|MIME_TYPE  |MIME_SOURCE   |MIME_PURPOSE |MIME_ORDER |
+-----------+--------------+-------------+-----------+
|image/jpeg |ube105252.jpg |normal       |1          |
+-----------+--------------+-------------+-----------+
|image/jpeg |bbd372670.jpg |logo         |2          |
+-----------+--------------+-------------+-----------+
|image/jpeg |ube105252.jpg |logo         |3          |
+-----------+--------------+-------------+-----------+
|image/jpeg |bbd372670.jpg |others       |4          |
+-----------+--------------+-------------+-----------+
|image/jpeg |bbd372670.jpg |others       |5          |
+-----------+--------------+-------------+-----------+

但我需要的是:

+-------------+------------+------------------+--------------+-------------+
|SUPPLIER_AID | MIME_TYPE  |    MIME_SOURCE   | MIME_PURPOSE |  MIME_ORDER |
+-------------+------------+------------------+--------------+-------------+
|9900026005   | image/jpeg |    ube105252.jpg | normal       |  1          |
+-------------+------------+------------------+--------------+-------------+
|9900026005   | image/jpeg |    bbd372670.jpg | logo         |  2          |
+-------------+------------+------------------+--------------+-------------+

1 个答案:

答案 0 :(得分:2)

您使用FROM OPENXML的方法已过时,不应再使用了。有更好的XML方法,如.node().value().query().modify()

将XML放入表中的方式非常好。一旦你有了它,你应该继续这样:

注意我使用声明的模拟表来模拟您的表格。

DECLARE @XMLwithOpenXML TABLE(XMLData XML,LoadedDateTime DATETIME);

INSERT INTO @XMLwithOpenXML VALUES
('<MIME_INFO>
    <MIME>
        <MIME_TYPE>image/jpeg</MIME_TYPE>
        <MIME_SOURCE>ube105252.jpg</MIME_SOURCE>
        <MIME_PURPOSE>normal</MIME_PURPOSE>
        <MIME_ORDER>1</MIME_ORDER>
    </MIME>
    <MIME>
        <MIME_TYPE>image/jpeg</MIME_TYPE>
        <MIME_SOURCE>bbd372670.jpg</MIME_SOURCE>
        <MIME_PURPOSE>logo</MIME_PURPOSE>
        <MIME_ORDER>2</MIME_ORDER>
    </MIME>
</MIME_INFO>',GETDATE());

此时,您的XML已成功进入您的表

CTE&#34;编号&#34;将使用固有顺序中的MIME读取所有.nodes()个元素,并相应地对其进行编号。

SELECT提取实际数据

WITH Numbered AS
(
    SELECT LoadedDateTime
          ,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS ID
          ,m.query('.') AS mime
    FROM @XMLwithOpenXML AS t
    CROSS APPLY t.XMLData.nodes('/MIME_INFO/MIME') AS A(m)
)
SELECT ID
      ,LoadedDateTime
      ,mime.value('(MIME/MIME_TYPE)[1]','nvarchar(max)') AS MIME_TYPE
      ,mime.value('(MIME/MIME_SOURCE)[1]','nvarchar(max)') AS MIME_SOURCE
      ,mime.value('(MIME/MIME_PURPOSE)[1]','nvarchar(max)') AS MIME_PURPOSE
      ,mime.value('(MIME/MIME_ORDER)[1]','nvarchar(max)') AS MIME_ORDER
FROM Numbered

结果

+----+-------------------------+------------+---------------+--------------+------------+
| ID | LoadedDateTime          | MIME_TYPE  | MIME_SOURCE   | MIME_PURPOSE | MIME_ORDER |
+----+-------------------------+------------+---------------+--------------+------------+
| 1  | 2016-09-15 16:37:30.730 | image/jpeg | ube105252.jpg | normal       | 1          |
+----+-------------------------+------------+---------------+--------------+------------+
| 2  | 2016-09-15 16:37:30.730 | image/jpeg | bbd372670.jpg | logo         | 2          |
+----+-------------------------+------------+---------------+--------------+------------+

更新

您没有显示完整的XML ...通过上面给出的示例,此代码可以提取您想要的所有内容:

WITH Numbered AS
(
    SELECT Id
          ,LoadedDateTime
          ,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS MimeRowNr
          ,a.value('@mode','nvarchar(max)') ARTICLE_MODE
          ,a.value('SUPPLIER_AID[1]','nvarchar(max)') AS SUPPLIER_AID
          ,m.query('.') AS mime
    FROM XMLwithOpenXML AS t
    CROSS APPLY t.XMLData.nodes('/BMECAT/T_NEW_CATALOG/ARTICLE') AS A(a)
    CROSS APPLY a.nodes('MIME_INFO/MIME') AS B(m)
)
SELECT Id
      ,MimeRowNr
      ,LoadedDateTime
      ,ARTICLE_MODE
      ,SUPPLIER_AID
      ,mime.value('(MIME/MIME_TYPE)[1]','nvarchar(max)') AS MIME_TYPE
      ,mime.value('(MIME/MIME_SOURCE)[1]','nvarchar(max)') AS MIME_SOURCE
      ,mime.value('(MIME/MIME_PURPOSE)[1]','nvarchar(max)') AS MIME_PURPOSE
      ,mime.value('(MIME/MIME_ORDER)[1]','int') AS MIME_ORDER
FROM Numbered;

结果

+----+-----------+-------------------------+--------------+--------------+-----------------+---------------+--------------+------------+
| Id | MimeRowNr | LoadedDateTime          | ARTICLE_MODE | SUPPLIER_AID | MIME_TYPE       | MIME_SOURCE   | MIME_PURPOSE | MIME_ORDER |
+----+-----------+-------------------------+--------------+--------------+-----------------+---------------+--------------+------------+
| 1  | 1         | 2016-09-16 09:32:53.570 | new          | 9900026005   | image/jpeg      | ube105252.jpg | normal       | 1          |
+----+-----------+-------------------------+--------------+--------------+-----------------+---------------+--------------+------------+
| 1  | 2         | 2016-09-16 09:32:53.570 | new          | 9900026005   | image/jpeg      | bbd372670.jpg | logo         | 2          |
+----+-----------+-------------------------+--------------+--------------+-----------------+---------------+--------------+------------+
| 1  | 3         | 2016-09-16 09:32:53.570 | new          | 9900026005   | image/jpeg      | ube305149.jpg | logo         | 3          |
+----+-----------+-------------------------+--------------+--------------+-----------------+---------------+--------------+------------+
| 1  | 4         | 2016-09-16 09:32:53.570 | new          | 9900026005   | image/jpeg      | ube108453.jpg | others       | 4          |
+----+-----------+-------------------------+--------------+--------------+-----------------+---------------+--------------+------------+
| 1  | 5         | 2016-09-16 09:32:53.570 | new          | 9900026005   | application/pdf | ube007100.pdf | others       | 5          |
+----+-----------+-------------------------+--------------+--------------+-----------------+---------------+--------------+------------+