2013-09-26 6 views
5

एसक्यूएल 2012 & का उपयोग कर एक्सएमएल को संग्रहीत प्रक्रिया में पारित किया गया है जो उस इनपुट को लेना चाहिए & प्रत्येक आइटम के लिए तालिका में एक पंक्ति लिखें एक्सएमएल का एक वर्ग जिसे संग्रहीत प्रक्रिया में पास किया जाता है। एक्सएमएल लगता है:एसक्यूएल 2012 - एक एक्सएमएल सूची (एक WHILE लूप के लिए बेहतर विकल्प) के माध्यम से पुनरावृत्त करें

<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 पंक्तियाँ एक तालिका (ऊपर प्रत्येक SendTo के लिए एक) में डाला जाना चाहिए, और प्रत्येक तालिका में MyMsg और MsgTime क्षेत्रों में एक ही मूल्य है।

मैं SendTo की संख्या की गणना प्राप्त कर सकता हूं और XML SendToList प्राप्त कर सकता हूं लेकिन मुझे नहीं पता कि इनसे सम्मिलित करने के लिए इसे कैसे पुन: सक्रिय किया जाए।

मैं XML में क्या प्राप्त करने के लिए निम्न SQL का उपयोग कर सकता हूं।

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 काम करता है, हालांकि, यह सही एक के बाद एक डालने कर रहा है। मैं सोच रहा था कि उपलब्ध विधियों को लूपिंग के बजाय इसे करने में सक्षम होना चाहिए, लेकिन मुझे ऐसा करने के लिए पर्याप्त रूप से नहीं पता कि मुझे क्या करना है।

किसी भी मदद या सुझाव की सराहना करेंगे।

उत्तर

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 

तुम सिर्फ में पंक्तियां सम्मिलित करना चाहते हैं कुछ मेज, तो आप एक साधारण डालने में ऐसा कर सकते हैं:

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

मैं सीधे एक टेबल में डालना होगा - आपका दूसरा उदाहरण बहुत अच्छा काम करता है। धन्यवाद! –

+0

क्या होगा यदि मैं डेटा को पढ़ना चाहता हूं और इसे एक चर में सहेजना चाहता हूं जो सामने के अंत में प्रदर्शित किया जाए? http://stackoverflow.com/questions/26426412/how-to-ensure-the-sql-is-able-to-read-all-xml-tag-data – SearchForKnowledge

+0

पहला विकल्प मुझे SendTo, MyMsg, MsgTime घोषित करने की आवश्यकता है – user3885927

संबंधित मुद्दे