【问题标题】:SQL Server 2014: Extracting data from XML using OpenXML and BulkColumnSQL Server 2014:使用 OpenXML 和 BulkColumn 从 XML 中提取数据
【发布时间】:2016-12-25 05:45:43
【问题描述】:

我正在尝试使用 OpenXMLBulkColumn 从一个大的 xml 文件中提取数据,然后将其保存到一个名为 badges 的新表中。 我也在执行一个 select 语句来显示表格的内容。 该文件存储在本地。该文件使用以属性为中心的映射,有数万行。 我使用的代码是:

    CREATE TABLE dbo.badges (
        Id              int,
        Name            NVARCHAR(1000),
        Date            date,
        Class           smallint,
        TagBased        nvarchar(10),

    );

    DECLARE @XMLDoc XML;    
    DECLARE @XMLDocID INT;  
    SELECT @XMLDoc = BulkColumn 
    FROM OPENROWSET(BULK 'C:\Users\Zuhair\Desktop\Badges.xml', SINGLE_BLOB);    

    EXEC sys.sp_xml_preparedocument @XMLDocID OUTPUT, @XMLDoc;

    SELECT  Id, Name, Date, Class, TagBased
    FROM    OPENXML(@XMLDocID, '/badges/row')
    WITH    (Id int 'Id',
                Name NVARCHAR(1000) 'Name',
                Date date 'Date',
                Class smallint 'Class',
                TagBased nvarchar(10) 'TagBased');

    INSERT INTO dbo.badges (Id, Name, Date, Class, TagBased)

    SELECT  *

    FROM    OPENXML(@XMLDocID, '/badges/row')
    WITH    (Id int 'Id',
                Name NVARCHAR(1000) 'Name',
                Date date 'Date',
                Class smallint 'Class',
                TagBased nvarchar(10) 'TagBased');

    exec sp_xml_removedocument @XMLDocID;

但是,当我执行上述代码时,我得到以下结果:

这是我正在使用的 XML 数据示例:

<badges>
  <row Id="1" UserId="2" Name="Autobiographer" Date="2010-08-11T18:25:03.937" Class="3" TagBased="False" />
  <row Id="2" UserId="3" Name="Autobiographer" Date="2010-08-11T18:25:03.997" Class="3" TagBased="False" />
  <row Id="3" UserId="4" Name="Autobiographer" Date="2010-08-11T18:25:04.107" Class="3" TagBased="False" />
  <row Id="4" UserId="22" Name="Autobiographer" Date="2010-08-11T19:35:05.283" Class="3" TagBased="False" />
  <row Id="5" UserId="33" Name="Autobiographer" Date="2010-08-11T19:35:05.330" Class="3" TagBased="False" />
  <row Id="6" UserId="27" Name="Autobiographer" Date="2010-08-11T19:40:05.490" Class="3" TagBased="False" />
  ...
</badges>

为什么我得到的是这个结果,而不是一个包含所需数据的表?

【问题讨论】:

标签: sql-server xml tsql sql-server-2014


【解决方案1】:

FROM OPENXML 的用法以及准备和删除文档的相关程序已过时,不应再使用。

试试这个:

DECLARE @xml XML =
'<badges>
  <row Id="1" UserId="2" Name="Autobiographer" Date="2010-08-11T18:25:03.937" Class="3" TagBased="False" />
  <row Id="2" UserId="3" Name="Autobiographer" Date="2010-08-11T18:25:03.997" Class="3" TagBased="False" />
  <row Id="3" UserId="4" Name="Autobiographer" Date="2010-08-11T18:25:04.107" Class="3" TagBased="False" />
  <row Id="4" UserId="22" Name="Autobiographer" Date="2010-08-11T19:35:05.283" Class="3" TagBased="False" />
  <row Id="5" UserId="33" Name="Autobiographer" Date="2010-08-11T19:35:05.330" Class="3" TagBased="False" />
  <row Id="6" UserId="27" Name="Autobiographer" Date="2010-08-11T19:40:05.490" Class="3" TagBased="False" />
</badges>';    

SELECT r.value('@Id','int') AS Id
      ,r.value('@UserId','int') AS UserId
      ,r.value('@Name','varchar(max)') AS Name
      ,r.value('@Date','datetime') AS [Date]
      ,r.value('@Class','int') AS Class
      ,r.value('@TagBased','bit') AS TagBased
FROM @xml.nodes('/badges/row') AS A(r)

更新完整(最小)代码

DECLARE @XMLDoc XML;        
SELECT @XMLDoc = BulkColumn 
FROM OPENROWSET(BULK 'C:\Users\Zuhair\Desktop\Badges.xml', SINGLE_BLOB) AS x;    

SELECT r.value('@Id','int') AS Id
      ,r.value('@UserId','int') AS UserId
      ,r.value('@Name','varchar(max)') AS Name
      ,r.value('@Date','datetime') AS [Date]
      ,r.value('@Class','int') AS Class
      ,r.value('@TagBased','bit') AS TagBased
FROM @XMLDoc.nodes('/badges/row') AS A(r)

【讨论】:

  • 源文件有数千行。如何连接到select语句?
  • @Taie,您可以使用与您目前使用的代码完全相同的代码来检索您的值。将FROM @xml.nodes 更改为FROM @XMLDoc.nodes 以使用现有变量。如果您没有得到结果,请尝试SELECT @XMLDoc 检查您是否成功读取了您的 XML。
  • @Taie,顺便说一句:我认为您现有的代码缺少 @ 标志来将您的目标标记为属性。如果没有@,您的代码将尝试查找元素...
  • 我仍然感到困惑并且仍然出现错误。你能告诉我最终的代码是什么吗?
【解决方案2】:

首先,我喜欢 Shnugo 的回答,我相信这是您应该遵循的道路。 对于您的具体问题,您得到所有​​ NULL 的原因是因为您正在从属性中提取数据而您忘记了所有 @。 试试下面的代码:

DECLARE @XMLDoc XML =
'<badges>
  <row Id="1" UserId="2" Name="Autobiographer" Date="2010-08-11T18:25:03.937" Class="3" TagBased="False" />
  <row Id="2" UserId="3" Name="Autobiographer" Date="2010-08-11T18:25:03.997" Class="3" TagBased="False" />
  <row Id="3" UserId="4" Name="Autobiographer" Date="2010-08-11T18:25:04.107" Class="3" TagBased="False" />
  <row Id="4" UserId="22" Name="Autobiographer" Date="2010-08-11T19:35:05.283" Class="3" TagBased="False" />
  <row Id="5" UserId="33" Name="Autobiographer" Date="2010-08-11T19:35:05.330" Class="3" TagBased="False" />
  <row Id="6" UserId="27" Name="Autobiographer" Date="2010-08-11T19:40:05.490" Class="3" TagBased="False" />
</badges>';    

DECLARE @XMLDocID INT;  
EXEC sys.sp_xml_preparedocument @XMLDocID OUTPUT, @XMLDoc;

SELECT  Id, Name, Date, Class, TagBased
FROM    OPENXML(@XMLDocID, '/badges/row')
WITH    (Id int '@Id',
            Name NVARCHAR(1000) '@Name',
            Date date '@Date',
            Class smallint '@Class',
            TagBased nvarchar(10) '@TagBased');

exec sp_xml_removedocument @XMLDocID;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 2021-12-23
    • 2016-03-16
    • 2017-07-23
    • 2016-12-29
    • 1970-01-01
    相关资源
    最近更新 更多