Insert into Select仅插入一行

时间:2016-07-20 18:50:24

标签: sql sql-server

我正在尝试将XML文件转换为MS SQL Server表,但它只插入第一行。有人可以解释一下吗?

我使用insert select导入数据。我已经尝试了所有的东西,但代码被剥离了,我看不出如何解决这个问题。

    CREATE DATABASE lei_1
    GO

    USE lei_1
    GO

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

    CREATE TABLE recordsx
    ( 
        LegalName VARCHAR(100),
        la_Line1 [varchar](100),
        la_Line2 [varchar](100),
        la_City [varchar](100),
        la_Region [varchar](100),
        la_Country [varchar](100),
        la_PostalCode [varchar](100)
    );

    INSERT INTO lei_1_table(XMLData, LoadedDateTime)
    SELECT CONVERT(XML, BulkColumn) AS BulkColumn, GETDATE() 
    FROM OPENROWSET(BULK 'C:\lei_example2.xml', SINGLE_BLOB) AS x;

    SELECT * FROM lei_1_table

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


    SELECT @XML = XMLData FROM lei_1_table


    EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML, '<lei:LEIData xmlns:lei="http://www.leiroc.org/data/schema/leidata/2014" />'

    SELECT LegalName, la_Line1, la_Line2, la_City, la_Region, la_Country, la_PostalCode
    FROM OPENXML(@hDoc, 'lei:LEIData')
    WITH 
    (
        LegalName [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalName',
        la_Line1 [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalAddress/lei:Line1',
        la_Line2 [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalAddress/lei:Line2',
        la_City [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalAddress/lei:City',
        la_Region [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalAddress/lei:Region',
        la_Country [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalAddress/lei:Country',
        la_PostalCode [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalAddress/lei:PostalCode'
    )

    insert into recordsx(LegalName, la_Line1, la_Line2, la_City, la_Region, la_Country, la_PostalCode)
    SELECT LegalName, la_Line1, la_Line2, la_City, la_Region, la_Country, la_PostalCode FROM OPENXML(@hDoc, 'lei:LEIData')
    WITH 
    (
        LegalName [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalName',
        la_Line1 [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalAddress/lei:Line1',
        la_Line2 [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalAddress/lei:Line2',
        la_City [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalAddress/lei:City',
        la_Region [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalAddress/lei:Region',
        la_Country [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalAddress/lei:Country',
        la_PostalCode [varchar](100) 'lei:LEIRecords/lei:LEIRecord/lei:Entity/lei:LegalAddress/lei:PostalCode'
    )

    SELECT * FROM recordsx


    EXEC sp_xml_removedocument @hDoc
    GO

这是我的XML:

<lei:LEIData xmlns:lei="http://www.leiroc.org/data/schema/leidata/2014">             
  <lei:LEIRecords>
<lei:LEIRecord>
  <lei:LEI>48510000JZ17NWGUA510</lei:LEI>
  <lei:Entity>
    <lei:LegalName>KDD - Centralna klirin</lei:LegalName>
    <lei:LegalAddress>
      <lei:Line1>Tivolska cesta 48</lei:Line1>
      <lei:City>Ljubljana</lei:City>
      <lei:Country>SI</lei:Country>
      <lei:PostalCode>1000</lei:PostalCode>
    </lei:LegalAddress>
  </lei:Entity>
</lei:LEIRecord>
<lei:LEIRecord>
  <lei:LEI>485100004VOFFO18DD84</lei:LEI>
  <lei:Entity>
    <lei:LegalName>NLB VITljana</lei:LegalName>
    <lei:LegalAddress>
      <lei:Line1>Trg republike 3</lei:Line1>
      <lei:City>Ljubljana</lei:City>
      <lei:Country>SI</lei:Country>
      <lei:PostalCode>1000</lei:PostalCode>
    </lei:LegalAddress>
  </lei:Entity>
</lei:LEIRecord>
  </lei:LEIRecords>
</lei:LEIData> 

2 个答案:

答案 0 :(得分:0)

这是因为您的查询只会获得包含文件全部内容的单行。

查看MS的文档。 https://msdn.microsoft.com/en-us/library/ms190312.aspx

  

SINGLE_CLOB通过将data_file读取为ASCII,将内容作为a返回   varchar(max)类型的单行,单列行集,使用   整理当前数据库。

我的猜测是你需要在插入过程中粉碎那个xml。

答案 1 :(得分:0)

问题是你选择xpath太浅了。以下查询返回xml。

中的2行
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML, '<lei:LEIData xmlns:lei="http://www.leiroc.org/data/schema/leidata/2014" />'

SELECT LegalName, la_Line1, la_Line2, la_City, la_Region, la_Country, la_PostalCode                      
FROM OPENXML(@hDoc, 'lei:LEIData/lei:LEIRecords/lei:LEIRecord')
WITH                          --^ here
(
    LegalName [varchar](100) 'lei:Entity/lei:LegalName',
    la_Line1 [varchar](100) 'lei:Entity/lei:LegalAddress/lei:Line1',
    la_Line2 [varchar](100) 'lei:Entity/lei:LegalAddress/lei:Line2',
    la_City [varchar](100) 'lei:Entity/lei:LegalAddress/lei:City',
    la_Region [varchar](100) 'lei:Entity/lei:LegalAddress/lei:Region',
    la_Country [varchar](100) 'lei:Entity/lei:LegalAddress/lei:Country',
    la_PostalCode [varchar](100) 'lei:Entity/lei:LegalAddress/lei:PostalCode'
)

--insert into recordsx(LegalName, la_Line1, la_Line2, la_City, la_Region, la_Country, la_PostalCode)
SELECT LegalName, la_Line1, la_Line2, la_City, la_Region, la_Country, la_PostalCode 
FROM OPENXML(@hDoc, 'lei:LEIData/lei:LEIRecords/lei:LEIRecord/lei:Entity')
WITH                          --^ here
(
    LegalName [varchar](100) 'lei:LegalName',
    la_Line1 [varchar](100) 'lei:LegalAddress/lei:Line1',
    la_Line2 [varchar](100) 'lei:LegalAddress/lei:Line2',
    la_City [varchar](100) 'lei:LegalAddress/lei:City',
    la_Region [varchar](100) 'lei:LegalAddress/lei:Region',
    la_Country [varchar](100) 'lei:LegalAddress/lei:Country',
    la_PostalCode [varchar](100) 'lei:LegalAddress/lei:PostalCode'
)

--SELECT * FROM recordsx


EXEC sp_xml_removedocument @hDoc

此外,如果您将@xml声明为XML类型,则可以使用.nodes()之类的原生xml方法等。
根据我的经验说实话,这些原生方法比你使用的openxml要慢。

本机xml方法的示例。

--from OP
DECLARE @XML AS XML
SELECT @XML = XMLData FROM lei_1_table

--@xml is already xml type. So use it.
--honor xmlns:lei="..." but not necessarily under the same name
;with xmlnamespaces('http://www.leiroc.org/data/schema/leidata/2014' as x)
--insert tbl goes here
--note [1]. value() requires a singleton
select t.v.value('../x:LEI[1]','varchar(100)') LEI -- note ../ for parent node
   ,t.v.value('x:LegalName[1]','varchar(100)') LegalName
   ,t.v.value('(x:LegalAddress/x:Line1)[1]','varchar(100)') Line1
   ,t.v.value('(x:LegalAddress/x:Line2)[1]','varchar(100)') Line2
   ,t.v.value('(x:LegalAddress/x:City)[1]','varchar(100)') City
   ,t.v.value('(x:LegalAddress/x:Region)[1]','varchar(100)') Region
   ,t.v.value('(x:LegalAddress/x:Country)[1]','varchar(100)') Country
   ,t.v.value('(x:LegalAddress/x:PostalCode)[1]','varchar(100)') PostalCode
from @xml.nodes('x:LEIData/x:LEIRecords/x:LEIRecord/x:Entity') t(v)