2015-03-31 1 views
3

У меня есть XML-файл, который мне нужно импортировать в базу данных SQL Server. Файл XML создается следующим образом:Импорт XML в SQL Server, разбитый на несколько строк

<report> 
    <deltagere> 
    <deltager> 
    <number>142555267</number> 
    <date>29-12-2006</date> 
    <name> 
     <name> 
     <from>01-05-2000</from> 
     <to>01-01-2003</to> 
     <text>foo</text> 
     </name> 
     <name> 
     <from>01-01-2003</from> 
     <to>29-12-2006</to> 
     <text>bzz</text> 
     </name> 
    </name> 
    <information> 
     <deltagertype>person</deltagertype> 
     <leader>John Smith</leader> 
     <status>Active</status> 
    </information> 
    <role>Responsible</role> 
    </deltager> 
    <deltager> 
     <number>4000134982</number> 
     <date>05-12-2007</date> 
     <name> 
     <name> 
      <from>07-07-2007</from> 
      <to>05-12-2007</to> 
      <text>bar</text> 
     </name> 
     </name> 
     <information> 
     <deltagertype>person</deltagertype> 
     <leader>Wolfgang Smith</leader> 
     <status>Active</status> 
     </information> 
     <role>Responsible</role> 
    </deltager> 
    ... 
    </deltagere> 
</report> 

Как вы можете видеть, атрибут name может содержать несколько имен. Мне удалось импортировать XML в мою базу данных, но только с атрибутом первого имени. Код я написал до сих пор:

DECLARE @XmlFile XML 

SELECT @XmlFile = BulkColumn 
FROM OPENROWSET(BULK 'C:\input.xml', SINGLE_BLOB) x; 

INSERT INTO dbo.deltagere(number, dato, nameFrom, nameTo, nameText, deltagertype, leader, deltagerStatus, deltagerRole) 
SELECT 
    number = deltagere.value('(number)[1]', 'bigint'), 
    dato = deltagere.value('(date)[1]', 'varchar(10)'), 
    nameFrom = deltagere.value('(name/name/from)[1]', 'varchar(10)'), 
    nameTo = deltagere.value('(name/name/to)[1]', 'varchar(10)'), 
    nameText = deltagere.value('(name/name/text)[1]', 'varchar(30)'), 
    deltagertype = deltagere.value('(information/deltagertype)[1]', 'varchar(20)'), 
    leader = deltagere.value('(information/leader)[1]', 'varchar(50)'), 
    deltagerStatus = deltagere.value('(information/status)[1]', 'varchar(50)'), 
    deltagerRole = deltagere.value('(role)[1]', 'varchar(50)') 
FROM 
    @XmlFile.nodes('/report/deltagere/deltager') AS XTbl(deltagere); 

Который дает мне этот выход:

| number  | dato  | nameFrom | nameTo  | nameText | deltagertype | ... 
| 142555267 | 29-12-2006 | 01-05-2000 | 01-01-2003 | foo  | person  | ... 
| 4000134982 | 05-12-2007 | 07-07-2007 | 05-12-2007 | bar  | person  | ... 

Я хотел бы иметь строку для каждого имени/названия. Так что-то вроде этого:

------------------------------------------------------- 
| number  | dato  | nameFrom | nameTo  | nameText | deltagertype | ... 
| 142555267 | 29-12-2006 | 01-05-2000 | 01-01-2003 | foo  | person  | ... 
| 142555267 | 29-12-2006 | 01-01-2003 | 29-12-2006 | bzz  | person  | ... 
| 4000134982 | 05-12-2007 | 07-07-2007 | 05-12-2007 | bar  | person  | ... 

и так далее.

Я действительно потерялся в том, как это сделать. Поэтому я надеюсь, что у кого-нибудь из вас есть идеи по изменению моего кода, чтобы разрешить этот или, возможно, другой подход к проблеме.

ответ

2

Попробуйте - вам нужно сделать второй .nodes() вызов, чтобы перечислить все <name> подузлы:

SELECT 
    number = deltagere.value('(number)[1]', 'bigint'), 
    dato = deltagere.value('(date)[1]', 'varchar(10)'), 
    -- NEW NEW NEW - read from `XC` pseudo columns to get 1-n names 
    nameFrom = XC.value('(from)[1]', 'varchar(10)'), 
    nameTo = XC.value('(to)[1]', 'varchar(10)'), 
    nameText = XC.value('(text)[1]', 'varchar(30)'), 
    deltagertype = deltagere.value('(information/deltagertype)[1]', 'varchar(20)'), 
    leader = deltagere.value('(information/leader)[1]', 'varchar(50)'), 
    deltagerStatus = deltagere.value('(information/status)[1]', 'varchar(50)'), 
    deltagerRole = deltagere.value('(role)[1]', 'varchar(50)') 
FROM 
    @XmlFile.nodes('/report/deltagere/deltager') AS XTbl(deltagere) 
CROSS APPLY 
    deltagere.nodes('name/name') AS XT2(XC) 
+1

Вы удивительны. Это было то, что мне нужно. Спасибо – Kasperhogh

+0

Возможно, вы можете помочь мне с другим вопросом. Что делать, если в некоторых узлах нет узлов . Затем вставляется 0 строк. Любой способ просто написать NULL в столбцах имен, если это так? – Kasperhogh

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