SQL 2012 - 迭代 XML 列表(WHILE 循环的更好替代方案)

2023-11-26

使用 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>

存储过程的输出应该是插入到表中的 5 行(每行 1 行)SendTo上面),并且每个都具有相同的值MyMsg and MsgTime该表中的字段。

我可以计算出数量SendTo并可以获得XMLSendToList但我不知道如何迭代它来进行插入。

我可以使用以下 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)

目前,我正在使用变量和WHILE循环遍历 SendToList 中的项目,但我知道必须有更好的方法。

SELECT @msgTo= @XML_In.value('(/MyXML/SendToList/SendTo[position()=sql:variable("@cnt")])[1]','VARCHAR(100)')

上面的内容让我获得了 SendToList 中每个项目的值。
如果我选择变量 @mlst,我可以看到需要循环的 XML 结构。

<SendToList>
   <SendTo>John</SendTo>
   <SendTo>James</SendTo>
   <SendTo>Rob</SendTo>
   <SendTo>Pete</SendTo>
   <SendTo>Sam</SendTo>
</SendToList>

尽管WHILE有效,它在另一个插入之后立即执行一个插入。我认为可用的方法应该能够完成这一切而不是循环,但我对使用它们来完成我需要做的事情了解不够。

将不胜感激任何帮助或建议。


如果您需要执行需要循环的操作(例如,您想向每个收件人发送电子邮件,则可以使用游标:

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

如果您只想将行插入到某个表中,您可以通过一次简单的插入来完成此操作:

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)

sql fiddle demo

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL 2012 - 迭代 XML 列表(WHILE 循环的更好替代方案) 的相关文章

随机推荐