2013-09-26 5 views
5

SQL 2012 &'u kullanarak, bu girdiyi almak için & girdisi olan her bir öğe için tabloya bir satır yazın. saklı yordama geçirilen bir XML bölümü.SQL 2012 - bir XML listesiyle yineleyin (WHILE döngüsüne daha iyi bir alternatif)

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

saklı yordam çıktısı bir tablo (yukarıdaki her SendTo için bir tane) yerleştirilen 5 satır olmalı ve her birinin tabloda MyMsg ve MsgTime alanlarda aynı değere sahiptir: gibi bir XML görünüyor.

SendTo numarasının sayısını alabilir ve XML'yi SendToList alabilir, ancak ekleme yapmak için bunu nasıl değiştireceğimi bilmiyorum.

XML'de neler olduğunu öğrenmek için aşağıdaki SQL'i kullanabilirim.

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) 

Şu anda, değişkenler ve SendToList öğeleri döngü için WHILE kullanıyorum, ama daha iyi bir yolu olmalı biliyorum.

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

Yukarıdakiler SendToList öğesindeki her öğenin değerini alır.
@mlst değişkenini seçersem, XML'in yapısını döngü yapmam gerektiğini görebilirim.

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

WHILE çalışıyor olsa da, birbiri ardına bir ekleme yapılır. Mevcut metotların döngü yapmak yerine hepsini yapabilmesi gerektiğini düşünüyordum ama yapmam gerekeni yapmak için onları kullanmam konusunda yeterince bilgi sahibi değilim.

Herhangi bir yardım veya öneriniz için teşekkür ederiz.

cevap

12

Eğer örneğin, bir imleç kullanabilirsiniz yerine, her alıcıya e-posta göndermek istediğiniz (bir döngü gerektirir şey yapmak gerekirse: sadece satır eklemek istiyorsanız

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 

bazı tablo, basit bir ekleme yapabilirsiniz:

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

+0

Doğrudan bir masaya yerleştiriyordum - ikinci örneğiniz harika çalıştı. Teşekkür ederim! –

+0

Verileri okumak ve ön uçta görüntülenecek bir değişkene kaydetmek istersem ne olur? http://stackoverflow.com/questions/26426412/how-to-ensure-the-sql-is-able-to-read-all-xml-tag-data – SearchForKnowledge

+0

İlk seçenek SendTo, MyMsg, MsgTime bildirimde bulundu – user3885927