1

我对此有点陌生,所以请多多包涵。我正在尝试从 xml 文档生成表。由于 XML 文档的某些内容,我不得不使用我不太熟悉的 convert 方法。结果我得到一个错误。我不知道为什么。我正在使用 Microsoft SQL Server 2016。

这是我的查询:

WITH XmlFile (Contents) AS 
(
    SELECT 
        CONVERT (XML, BulkColumn,2)
    FROM 
        OPENROWSET (BULK 'C:\Users\Owner\Documents\congress\House votes\114 congress 2015\passage\roll705.xml', SINGLE_BLOB) AS roll705
)
SELECT *
FROM XmlFile
GO

DECLARE @hdoc int

EXEC sp_xml_preparedocument @hdoc OUTPUT, xmlfile

SELECT *
FROM OPENXML (@hdoc, '/rollcall-vote/vote-metadata', 1)
WITH (
    congress tinyint,
    [session] char(3),
    chamber varchar(40),
    [rollcall-num] smallint,
    [legis-num] varchar(20),
    [vote-question] varchar(1000),
    [vote-result] varchar (20),
    [action-date] date,
    [vote-desc] varchar(1000)
)

EXEC sp_xml_removedocument @hdoc

这是我的 XML 文档的婴儿版

<?xml-stylesheet type="text/xsl" href="http://clerk.house.gov/evs/vote.xsl"?>
<rollcall-vote>
  <vote-metadata>
    <majority>R</majority>
    <congress>114</congress>
    <session>1st</session>
    <chamber>U.S. House of Representatives</chamber>
    <rollcall-num>705</rollcall-num>
    <legis-num>H R 2029</legis-num>
    <vote-question>On Concurring in Senate Amdt with Amdt Specified in Section 3(a) of H.Res. 566</vote-question>
    <vote-type>YEA-AND-NAY</vote-type>
    <vote-result>Passed</vote-result>
    <action-date>18-Dec-2015</action-date>
    <action-time time-etz="09:49">9:49 AM</action-time>
    <vote-desc>Making appropriations for military construction, the Department of Veterans Affairs, and related agencies for the fiscal year ending September 30, 2016, and for other purposes</vote-desc>
</rollcall-vote>

我的错误图片

更新

这就是我现在的位置:

CREATE TABLE [dbo].[staagingTable](
    [Counter] INT NOT NULL,
    [majority] [nvarchar](max) NULL,
    [congress] [int] NULL,
    [session] [nvarchar](max) NULL,
    [chamber] [nvarchar](max) NULL,
    [rollcall-num] [int] NULL,
    [legis-num] [nvarchar](max) NULL,
    [vote-question] [nvarchar](max) NULL,
    [vote-type] [nvarchar](max) NULL,
    [vote-result] [nvarchar](max) NULL,
    [action-date] [nvarchar](max) NULL,
    [action-time] [nvarchar](max) NULL,
    [vote-desc] [nvarchar](max) NULL,
    [sourceXML] [XML] NULL
);
GO

DECLARE @Counter INT=1;
DECLARE @command VARCHAR(MAX);

WHILE @Counter<800
BEGIN
    SET @command=
    '
    DECLARE @xml XML=
    (
    SELECT BulkColumn
    FROM OPENROWSET (BULK ''C:\Users\Owner\Documents\congress\House votes\114 congress 2015\Passage\roll' +  CAST(@Counter AS VARCHAR(10)) + '.xml'', SINGLE_BLOB) AS c
    );

    INSERT INTO dbo.stagingTable(Counter,majority,congress,[session],chamber
              ,[rollcall-num],[legis-num],[legislator],[state],[party],[vote],[vote-question],[vote-type]
              ,[vote-result],[action-date],[action-time],[vote-desc],)
    SELECT ' +  CAST(@Counter AS VARCHAR(10)) + 
         ',v.value(N''../maority[1]'',N''nvarchar(max)'') 
          ,v.value(N''../congress[1]'',N''int'') 
          ,v.value(N''../session[1]'',N''nvarchar(max)'') 
          ,v.value(N''../chamber[1]'',N''nvarchar(max)'')
          ,v.value(N''../rollcall-num[1]'',N''int'') 
          ,v.value(N''../legis-num[1]'',N''nvarchar(max)'') 
          ,v.value(N''../vote-question[1]'',N''nvarchar(max)'')
          ,v.value(N''../vote-type[1]'',N''nvarchar(max)'') 
          ,v.value(N''../vote-result[1]'',N''nvarchar(max)'') 
          ,v.value(N''../action-date[1]'',N''nvarchar(max)'') 
          ,v.value(N''../action-time[1]'',N''nvarchar(max)'') 
          ,v.value(N''../vote-desc[1]'',N''nvarchar(max)'') 
          ,@xml
    FROM @xml.nodes(N''/rollcall-vote/vote-metadata'') AS A(v);
    ';
    BEGIN TRY
EXEC(@command);
END TRY
BEGIN CATCH
END CATCH;
    SET @Counter=@Counter+1;
END
SELECT * FROM dbo.staagingTable;
GO
DROP TABLE dbo.staagingTable;

这是我文件夹中数据的屏幕截图 这是我对 catch 块的改动的图片

更新

这是我的查询。

CREATE TABLE [dbo].[staagingTable](
    [Counter] INT NOT NULL,
    [majority] [nvarchar](max) NULL,
    [congress] [int] NULL,
    [session] [nvarchar](max) NULL,
    [chamber] [nvarchar](max) NULL,
    [rollcall-num] [int] NULL,
    [legis-num] [nvarchar](max) NULL,
    [vote-question] [nvarchar](max) NULL,
    [vote-type] [nvarchar](max) NULL,
    [vote-result] [nvarchar](max) NULL,
    [action-date] [nvarchar](max) NULL,
    [action-time] [nvarchar](max) NULL,
    [vote-desc] [nvarchar](max) NULL,
    [sourceXML] [XML] NULL
);
GO

DECLARE @Counter INT=1;
DECLARE @command VARCHAR(MAX);

WHILE @Counter<800
BEGIN
    SET @command=
    '
    DECLARE @xml XML=
    (
    SELECT BulkColumn
    FROM OPENROWSET (BULK ''C:\Users\Owner\Documents\congress\House votes\114 congress 2015\Passage\roll' + REPLACE(STR(@Counter,3),' ','0') + CAST(@Counter AS VARCHAR(10)) + '.xml'', SINGLE_BLOB) AS c
    );

    INSERT INTO dbo.stagingTable(Counter,majority,congress,[session],chamber
              ,[rollcall-num],[legis-num],[vote-question],[vote-type]
              ,[vote-result],[action-date],[action-time],[vote-desc],)
    SELECT ' +  CAST(@Counter AS VARCHAR(10)) + 
         ',v.value(N''majority[1]'',N''nvarchar(max)'') 
          ,v.value(N''congress[1]'',N''int'') 
          ,v.value(N''session[1]'',N''nvarchar(max)'') 
          ,v.value(N''chamber[1]'',N''nvarchar(max)'')
          ,v.value(N''rollcall-num[1]'',N''int'') 
          ,v.value(N''legis-num[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-question[1]'',N''nvarchar(max)'')
          ,v.value(N''vote-type[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-result[1]'',N''nvarchar(max)'') 
          ,v.value(N''action-date[1]'',N''nvarchar(max)'') 
          ,v.value(N''action-time[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-desc[1]'',N''nvarchar(max)'') 
          ,@xml
    FROM @xml.nodes(N''/rollcall-vote/vote-metadata'') AS A(v);
    ';
    BEGIN TRY
EXEC(@command);
END TRY
BEGIN CATCH print 'error'
END CATCH;
    SET @Counter=@Counter+1;
END
SELECT * FROM dbo.staagingTable;
GO
DROP TABLE dbo.staagingTable;

执行上述查询的结果

更新

CREATE TABLE [dbo].[staagingTable](
    [Counter] INT NOT NULL,
    [majority] [nvarchar](max) NULL,
    [congress] [int] NULL,
    [session] [nvarchar](max) NULL,
    [chamber] [nvarchar](max) NULL,
    [rollcall-num] [int] NULL,
    [legis-num] [nvarchar](max) NULL,
    [vote-question] [nvarchar](max) NULL,
    [vote-type] [nvarchar](max) NULL,
    [vote-result] [nvarchar](max) NULL,
    [action-date] [nvarchar](max) NULL,
    [action-time] [nvarchar](max) NULL,
    [vote-desc] [nvarchar](max) NULL,
    [sourceXML] [XML] NULL
);
GO

DECLARE @Counter INT=1;
DECLARE @command VARCHAR(MAX);

WHILE @Counter<800
BEGIN
    SET @command=
    '
    DECLARE @xml XML=
    (
    SELECT BulkColumn
    FROM OPENROWSET (BULK ''C:\Users\Owner\Documents\congress\House votes\114 congress 2015\Passage\roll' + REPLACE(STR(@Counter,3),' ','0') + CAST(@Counter AS VARCHAR(10)) + '.xml'', SINGLE_BLOB) AS c
    );

    INSERT INTO dbo.stagingTable(Counter,majority,congress,[session],chamber
              ,[rollcall-num],[legis-num],[vote-question],[vote-type]
              ,[vote-result],[action-date],[action-time],[vote-desc],)
    SELECT ' +  CAST(@Counter AS VARCHAR(10)) + 
         ',v.value(N''majority[1]'',N''nvarchar(max)'') 
          ,v.value(N''congress[1]'',N''int'') 
          ,v.value(N''session[1]'',N''nvarchar(max)'') 
          ,v.value(N''chamber[1]'',N''nvarchar(max)'')
          ,v.value(N''rollcall-num[1]'',N''int'') 
          ,v.value(N''legis-num[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-question[1]'',N''nvarchar(max)'')
          ,v.value(N''vote-type[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-result[1]'',N''nvarchar(max)'') 
          ,v.value(N''action-date[1]'',N''nvarchar(max)'') 
          ,v.value(N''action-time[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-desc[1]'',N''nvarchar(max)'') 
          ,v.value(N''sourceXML[1]'',N''XML)'')
    FROM @xml.nodes(N''/rollcall-vote/vote-metadata'') AS A(v);
    ';
    BEGIN TRY
EXEC(@command);
END TRY
BEGIN CATCH print 'error'
END CATCH;
    SET @Counter=@Counter+1;
END
SELECT * FROM dbo.staagingTable;
GO
DROP TABLE dbo.staagingTable;

执行时

带有 xmls 的文件夹 信息

更新

CREATE TABLE [dbo].[staagingTable](
    [Counter] INT NOT NULL,
    [majority] [nvarchar](max) NULL,
    [congress] [int] NULL,
    [session] [nvarchar](max) NULL,
    [chamber] [nvarchar](max) NULL,
    [rollcall-num] [int] NULL,
    [legis-num] [nvarchar](max) NULL,
    [vote-question] [nvarchar](max) NULL,
    [vote-type] [nvarchar](max) NULL,
    [vote-result] [nvarchar](max) NULL,
    [action-date] [nvarchar](max) NULL,
    [action-time] [nvarchar](max) NULL,
    [vote-desc] [nvarchar](max) NULL,
    [sourceXML] [XML] NULL
);
GO

DECLARE @Counter INT=1;
DECLARE @command VARCHAR(MAX);

WHILE @Counter<800
BEGIN
    SET @command=
    '
    DECLARE @xml XML=
    (
    SELECT BulkColumn
    FROM OPENROWSET (BULK ''C:\Users\Owner\Documents\congress\House votes\114 congress 2015\Passage\roll' + REPLACE(STR(@Counter,3),' ','0') + CAST(@Counter AS VARCHAR(10)) + '.xml'', SINGLE_BLOB) AS c
    );

    INSERT INTO dbo.stagingTable(Counter,majority,congress,[session],chamber
              ,[rollcall-num],[legis-num],[vote-question],[vote-type]
              ,[vote-result],[action-date],[action-time],[vote-desc],)
    SELECT ' +  CAST(@Counter AS VARCHAR(10)) + 
         ',v.value(N''majority[1]'',N''nvarchar(max)'') 
          ,v.value(N''congress[1]'',N''int'') 
          ,v.value(N''session[1]'',N''nvarchar(max)'') 
          ,v.value(N''chamber[1]'',N''nvarchar(max)'')
          ,v.value(N''rollcall-num[1]'',N''int'') 
          ,v.value(N''legis-num[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-question[1]'',N''nvarchar(max)'')
          ,v.value(N''vote-type[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-result[1]'',N''nvarchar(max)'') 
          ,v.value(N''action-date[1]'',N''nvarchar(max)'') 
          ,v.value(N''action-time[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-desc[1]'',N''nvarchar(max)'') 
          ,@xml
    FROM @xml.nodes(N''/rollcall-vote/vote-metadata'') AS A(v);
    ';
    BEGIN TRY
EXEC(@command);
END TRY
BEGIN CATCH print ERROR_MESSAGE()
END CATCH;
    SET @Counter=@Counter+1;
END
SELECT * FROM dbo.staagingTable;
GO
DROP TABLE dbo.staagingTable;

错误

新错误

在此处输入图像描述 在此处输入图像描述

更新

CREATE TABLE [dbo].[staagingTable](
    [Counter] INT NOT NULL,
    [majority] [nvarchar](max) NULL,
    [congress] [int] NULL,
    [session] [nvarchar](max) NULL,
    [chamber] [nvarchar](max) NULL,
    [rollcall-num] [int] NULL,
    [legis-num] [nvarchar](max) NULL,
    [vote-question] [nvarchar](max) NULL,
    [vote-type] [nvarchar](max) NULL,
    [vote-result] [nvarchar](max) NULL,
    [action-date] [nvarchar](max) NULL,
    [action-time] [nvarchar](max) NULL,
    [vote-desc] [nvarchar](max) NULL,
    [sourceXML] [XML] NULL
);
GO

DECLARE @Counter INT=1;
DECLARE @command VARCHAR(MAX);

WHILE @Counter<800
BEGIN
    SET @command=
    '
    DECLARE @xml XML=
    (
    SELECT BulkColumn
    FROM OPENROWSET (BULK ''C:\Users\Owner\Documents\congress\House votes\114 congress 2015\Passage\roll' + REPLACE(STR(@Counter,3),' ','0') + CAST(@Counter AS VARCHAR(10)) + '.xml'', SINGLE_BLOB) AS c
    );

    INSERT INTO dbo.stagingTable(Counter,majority,congress,[session],chamber
              ,[rollcall-num],[legis-num],[vote-question],[vote-type]
              ,[vote-result],[action-date],[action-time],[vote-desc],[sourceXML])
    SELECT ' +
         ',v.value(N''majority[1]'',N''nvarchar(max)'') 
          ,v.value(N''congress[1]'',N''int'') 
          ,v.value(N''session[1]'',N''nvarchar(max)'') 
          ,v.value(N''chamber[1]'',N''nvarchar(max)'')
          ,v.value(N''rollcall-num[1]'',N''int'') 
          ,v.value(N''legis-num[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-question[1]'',N''nvarchar(max)'')
          ,v.value(N''vote-type[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-result[1]'',N''nvarchar(max)'') 
          ,v.value(N''action-date[1]'',N''nvarchar(max)'') 
          ,v.value(N''action-time[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-desc[1]'',N''nvarchar(max)'') 
          ,@xml
    FROM @xml.nodes(N''/rollcall-vote/vote-metadata'') AS A(v);
    ';
    BEGIN TRY
EXEC(@command);
END TRY
BEGIN CATCH print ERROR_MESSAGE()
END CATCH;
    SET @Counter=@Counter+1;
END
SELECT * FROM dbo.staagingTable;
GO
DROP TABLE dbo.staagingTable;

另一个更新

CREATE TABLE [dbo].[staagingTable](
    [Counter] INT NOT NULL,
    [majority] [nvarchar](max) NULL,
    [congress] [int] NULL,
    [session] [nvarchar](max) NULL,
    [chamber] [nvarchar](max) NULL,
    [rollcall-num] [int] NULL,
    [legis-num] [nvarchar](max) NULL,
    [vote-question] [nvarchar](max) NULL,
    [vote-type] [nvarchar](max) NULL,
    [vote-result] [nvarchar](max) NULL,
    [action-date] [nvarchar](max) NULL,
    [action-time] [nvarchar](max) NULL,
    [vote-desc] [nvarchar](max) NULL,
    [sourceXML] [XML] NULL
);
GO

DECLARE @Counter INT=1;
DECLARE @command VARCHAR(MAX);

WHILE @Counter<800
BEGIN
    SET @command=
    '
    DECLARE @xml XML=
    (
    SELECT BulkColumn
    FROM OPENROWSET (BULK ''C:\Users\Owner\Documents\congress\House votes\114 congress 2015\Passage\roll' + REPLACE(STR(@Counter,3),' ','0') + '.xml'', SINGLE_BLOB) AS c
    );

    INSERT INTO dbo.staagingTable(Counter,majority,congress,[session],chamber
              ,[rollcall-num],[legis-num],[vote-question],[vote-type]
              ,[vote-result],[action-date],[action-time],[vote-desc],[sourceXML])
    SELECT ' +  CAST(@Counter AS VARCHAR(10)) + 
         ',v.value(N''majority[1]'',N''nvarchar(max)'') 
          ,v.value(N''congress[1]'',N''int'') 
          ,v.value(N''session[1]'',N''nvarchar(max)'') 
          ,v.value(N''chamber[1]'',N''nvarchar(max)'')
          ,v.value(N''rollcall-num[1]'',N''int'') 
          ,v.value(N''legis-num[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-question[1]'',N''nvarchar(max)'')
          ,v.value(N''vote-type[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-result[1]'',N''nvarchar(max)'') 
          ,v.value(N''action-date[1]'',N''nvarchar(max)'') 
          ,v.value(N''action-time[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-desc[1]'',N''nvarchar(max)'') 
          ,@xml
    FROM @xml.nodes(N''/rollcall-vote/vote-metadata'') AS A(v);
    ';
    BEGIN TRY
EXEC(@command);
END TRY
BEGIN CATCH print ERROR_MESSAGE()
END CATCH;
    SET @Counter=@Counter+1;
END
SELECT * FROM dbo.staagingTable;
GO
DROP TABLE dbo.staagingTable;

在下图中,您可以看到错误。不存在的文件具有相同的旧批量文件未找到消息。但是确实存在的文件(如 006、012 和 014)有不同的信息。

截屏

4

1 回答 1

1

作为你所有通过的问题的本质,我选择

  • 同一个目录中有很多xml文件(嗯,很多在一个,很多在另一个)
  • 所有文件具有相同的结构
  • 您想将它们读入表格

我的假设(你必须适应你的需要)

  • 名称是可计算的(在我的例子中是“xml1”、“xml2”、“xml3”......)
  • 对于我的测试场景,我创建了三个 XML 文件(称为“xml1.xml”、“xml2.xml”和“xml3.xml”,其中包含您的婴儿版本的内容。因此循环停止在4

尝试这个

  • 我创建了一个具有合适结构的临时表(在第一步中不要担心日期时间转换!)
  • 我使用计数器在循环中计算文件名
  • 我使用WHILE循环
  • 在这个循环中,完整的语句是动态创建的。它会将您的 XML 从文件中读取到变量中,并将所有值推送到表中。
  • EXEC这个命令执行
  • 用一个简单的方法检查结果SELECT

这是代码

CREATE TABLE [dbo].[stagingTable](
    [Counter] INT NOT NULL,
    [majority] [nvarchar](max) NULL,
    [congress] [int] NULL,
    [session] [nvarchar](max) NULL,
    [chamber] [nvarchar](max) NULL,
    [rollcall-num] [int] NULL,
    [legis-num] [nvarchar](max) NULL,
    [vote-question] [nvarchar](max) NULL,
    [vote-type] [nvarchar](max) NULL,
    [vote-result] [nvarchar](max) NULL,
    [action-date] [nvarchar](max) NULL,
    [action-time] [nvarchar](max) NULL,
    [vote-desc] [nvarchar](max) NULL
);
GO

DECLARE @Counter INT=1;
DECLARE @command VARCHAR(MAX);

WHILE @Counter<4
BEGIN
    SET @command=
    '
    DECLARE @xml XML=
    (
    SELECT BulkColumn
    FROM OPENROWSET (BULK ''C:\StackOverflow\xml' +  CAST(@Counter AS VARCHAR(10)) + '.xml'', SINGLE_BLOB) AS c
    );

    INSERT INTO dbo.stagingTable(Counter,majority,congress,[session],chamber
              ,[rollcall-num],[legis-num],[vote-question],[vote-type]
              ,[vote-result],[action-date],[action-time],[vote-desc])
    SELECT ' +  CAST(@Counter AS VARCHAR(10)) + 
         ',v.value(N''maority[1]'',N''nvarchar(max)'') 
          ,v.value(N''congress[1]'',N''int'') 
          ,v.value(N''session[1]'',N''nvarchar(max)'') 
          ,v.value(N''chamber[1]'',N''nvarchar(max)'')
          ,v.value(N''rollcall-num[1]'',N''int'') 
          ,v.value(N''legis-num[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-question[1]'',N''nvarchar(max)'')
          ,v.value(N''vote-type[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-result[1]'',N''nvarchar(max)'') 
          ,v.value(N''action-date[1]'',N''nvarchar(max)'') 
          ,v.value(N''action-time[1]'',N''nvarchar(max)'') 
          ,v.value(N''vote-desc[1]'',N''nvarchar(max)'') 
    FROM @xml.nodes(N''/rollcall-vote/vote-metadata'') AS A(v);
    ';
    EXEC(@command);
    SET @Counter=@Counter+1;
END
SELECT * FROM dbo.stagingTable;
GO
DROP TABLE dbo.stagingTable;

更新

如果文件名是可计算的,但有差距,只需将简单更改EXEC(@cmd)为:

BEGIN TRY
EXEC(@command);
END TRY
BEGIN CATCH
--Might make sense to write some error meta data into a log table
END CATCH

这将忽略所有未找到文件的错误...

于 2017-02-21T22:25:45.757 回答