我正在尝试使用XQuery将XML插入到表中。有些节点是多个节点,但表中只有一列,所以我需要连接相同的节点。
如何迭代"INSERT ... SELECT ... FROM @xmlDoc.nodes ..."
类型的查询。
以下是我的xml文件的示例
<Persons>
<Person>
<FirstName>aaa</FirstName>
<LastName>bbb</LastName>
<DocumentNumber>AA 1234</DocumentNumber>
<DocumentNumber>BB 1234</DocumentNumber>
<WorkPlace>AAA Ltd</WorkPlace>
<WorkPlace>BBB Ltd</WorkPlace>
</Person>
<Person>
<FirstName>ccc</FirstName>
<LastName>ddd</LastName>
<DocumentNumber>CCC 1234</DocumentNumber>
<DocumentNumber>DDD 1234</DocumentNumber>
<DocumentNumber>EEE 1234</DocumentNumber>
<WorkPlace>CCC Ltd</WorkPlace>
<WorkPlace>DDD Ltd</WorkPlace>
</Person>
</Persons>
感谢。
答案 0 :(得分:2)
这是一个使用cte的版本,首先在xml列中隔离DocumentNumber和WorkPlace,然后使用for xml path('')来连接值。
declare @xml xml
set @xml =
'
<Persons>
<Person>
<FirstName>aaa</FirstName>
<LastName>bbb</LastName>
<DocumentNumber>AA 1234</DocumentNumber>
<DocumentNumber>BB 1234</DocumentNumber>
<WorkPlace>AAA Ltd</WorkPlace>
<WorkPlace>BBB Ltd</WorkPlace>
</Person>
<Person>
<FirstName>ccc</FirstName>
<LastName>ddd</LastName>
<DocumentNumber>CCC 1234</DocumentNumber>
<DocumentNumber>DDD 1234</DocumentNumber>
<DocumentNumber>EEE 1234</DocumentNumber>
<WorkPlace>CCC Ltd</WorkPlace>
<WorkPlace>DDD Ltd</WorkPlace>
</Person>
</Persons>
'
;with cte as
(
select
p.value('FirstName[1]', 'varchar(50)') as FirstName,
p.value('LastName[1]', 'varchar(50)') as LastName,
p.query('DocumentNumber') as docXML,
p.query('WorkPlace') as workXML
from
@xml.nodes('Persons/Person') p(p)
)
select
FirstName,
LastName,
(select d.value('.', 'varchar(100)')+' '
from cte.docXML.nodes('DocumentNumber') d(d)
for xml path('')) as DocumentNumber,
(select w.value('.', 'varchar(100)')+' '
from cte.workXML.nodes('WorkPlace') w(w)
for xml path('')) as WorkPlace
from cte
答案 1 :(得分:1)
您的XML组织非常糟糕......问题在于<DocumentNumber>
和<WorkPlace>
实体的多个条目直接位于<Person>
内,而不在其自己的“容器”节点内。
这使得解析得非常困难.....
如果您只想抓取名字,可以使用:
DECLARE @input XML = '<Persons>
<Person>
<FirstName>aaa</FirstName>
<LastName>bbb</LastName>
<DocumentNumber>AA 1234</DocumentNumber>
<DocumentNumber>BB 1234</DocumentNumber>
<WorkPlace>AAA Ltd</WorkPlace>
<WorkPlace>BBB Ltd</WorkPlace>
</Person>
<Person>
<FirstName>ccc</FirstName>
<LastName>ddd</LastName>
<DocumentNumber>CCC 1234</DocumentNumber>
<DocumentNumber>DDD 1234</DocumentNumber>
<DocumentNumber>EEE 1234</DocumentNumber>
<WorkPlace>CCC Ltd</WorkPlace>
<WorkPlace>DDD Ltd</WorkPlace>
</Person>
</Persons>'
SELECT
Person.value('(FirstName)[1]', 'varchar(50)') 'First Name',
Person.value('(LastName)[1]', 'varchar(50)') 'Last Name'
FROM
@input.nodes('/Persons/Person') AS Persons(Person)
当然,在选择存储信息之前,您还可以执行INSERT INTO dbo.YourTable(FirstName, LastName)
。
但是又一次:尝试将这些<DocumentNumber>
和<WorkPlace>
节点设置为正确的格式真的很难.....你要么最终复制数据,要么你必须做第二次第三次解析传递以正确存储这些东西。