2016-07-20 5 views
0

Я пытаюсь преобразовать 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> 
+0

Вам нужно показать свой xml. – granadaCoder

+0

Ну ваш пример, кажется, загружает все просто отлично. В чем именно проблема? –

+0

Спасибо, когда я запустил его в MS SQL Server, он создает только первую строку. –

ответ

0

Проблема в том, что вы выбрали xpath слишком мелким. Следующий запрос возвращает 2 строки от вас xml.

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 типа, то вы можете использовать собственные методы XML как .nodes() и так далее.
Чтобы сказать правду в моем опыте, эти натурные методы медленнее, чем openxml, которые вы используете.

Пример собственных методов xml.

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

[email protected] 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) 
+0

Отлично, что дает мне что-то поработать над –

+0

Это прекрасно. Спасибо @АлексКудряшев –

0

Это потому, что ваш запрос только когда-нибудь, чтобы получить одну строку со всем содержимым файла.

Глядя на документацию от MS. https://msdn.microsoft.com/en-us/library/ms190312.aspx

SINGLE_CLOB При чтении data_file в ASCII, возвращает содержимое в качестве однорядной, один столбец набора строк типа VARCHAR (макс), с использованием сортировки текущей базы данных.

Мое предположение, вам нужно будет уничтожить этот xml во время вашей вставки.

+0

Спасибо, но я уже измельчил его, используя встроенную хранимую процедуру TSQL. Sp_xml_preparedocument –

Смежные вопросы