ste*_*e_o 5 xml sql t-sql sql-server sqlxml
使用SQL 2012并将XML传递到存储过程,该存储过程必须接受该输入并为传递给存储过程的XML部分中的每个项目写一行.XML看起来像:
<MyXML>
<MyMsg>My Text Message</MyMsg>
<MsgTime>2013-09-25 10:52:37.098</MsgTime>
<SendToList>
<SendTo>John</SendTo>
<SendTo>James</SendTo>
<SendTo>Rob</SendTo>
<SendTo>Pete</SendTo>
<SendTo>Sam</SendTo>
</SendToList>
</MyXML>
Run Code Online (Sandbox Code Playgroud)
存储过程的输出应该是插入表中的5行(SendTo
上面各有一行),并且每个表在该表中的MyMsg
和MsgTime
字段中具有相同的值.
我可以得到数量的计数,SendTo
并可以获得XML,SendToList
但我不知道如何迭代它来进行插入.
我可以使用以下SQL来获取XML中的内容.
SELECT
x.value('(/MyXML/MyMsg)[1]', 'VARCHAR(1024)'),
x.value('(/MyXML/MsgTime)[1]', 'DATETIME'),
@max = x.query('<e> { count(/MyXML/SendToList/SendTo) } </e>').value('e[1]','int'),
@mlst = x.query('/MyXML/SendTo')
FROM @XML_In.nodes('//MyXML') i(x)
Run Code Online (Sandbox Code Playgroud)
目前,我正在使用变量和a WHILE
来遍历SendToList中的项目,但我知道必须有更好的方法.
SELECT @msgTo= @XML_In.value('(/MyXML/SendToList/SendTo[position()=sql:variable("@cnt")])[1]','VARCHAR(100)')
Run Code Online (Sandbox Code Playgroud)
上面的内容为我提供了SendToList中每个项目的值.
如果我选择变量@mlst,我可以看到我需要循环的XML结构.
<SendToList>
<SendTo>John</SendTo>
<SendTo>James</SendTo>
<SendTo>Rob</SendTo>
<SendTo>Pete</SendTo>
<SendTo>Sam</SendTo>
</SendToList>
Run Code Online (Sandbox Code Playgroud)
即使是WHILE
作品,它也会一个接一个地插入.我认为可用的方法应该能够完成而不是循环,但我不知道如何使用它们做我需要做的事情.
将不胜感激任何帮助或建议.
Rom*_*kar 12
如果您需要执行需要循环的操作(例如,您希望向每个收件人发送电子邮件,那么您可以使用游标:
declare cur cursor local fast_forward for
select
s.c.value('(text())[1]', 'nvarchar(max)') as SendTo,
m.c.value('(MyMsg/text())[1]', 'nvarchar(max)') as MyMsg,
m.c.value('(MsgTime/text())[1]', 'nvarchar(max)') as MsgTime
from @XML_In.nodes('MyXML') as m(c)
outer apply m.c.nodes('SendToList/SendTo') as s(c)
open cur
while 1 = 1
begin
fetch cur into @SendTo, @MyMsg, @MsgTime
if @@fetch_status <> 0 break
--=======================================
-- do what you need here
--=======================================
end
close cur
deallocate cur
Run Code Online (Sandbox Code Playgroud)
如果您只想在某些表中插入行,可以在一个简单的插入中执行此操作:
insert into <Your table>
(
SendTo, MyMsg, MsgTime
)
select
s.c.value('(text())[1]', 'nvarchar(max)') as SendTo,
m.c.value('(MyMsg/text())[1]', 'nvarchar(max)') as MyMsg,
m.c.value('(MsgTime/text())[1]', 'nvarchar(max)') as MsgTime
from @XML_In.nodes('MyXML') as m(c)
outer apply m.c.nodes('SendToList/SendTo') as s(c)
Run Code Online (Sandbox Code Playgroud)