मैं आपको एक उत्तर और एक अनुमान दे सकता हूं:
सबसे पहले मैं एक घोषित तालिका चर का उपयोग नकली करने के लिए . करता हूं आपका परिदृश्य:
DECLARE @tbl TABLE(s NVARCHAR(MAX));
INSERT INTO @tbl VALUES
(N'<root>
<SomeElement>This is first text of element1
<InnerElement>This is text of inner element1</InnerElement>
This is second text of element1
</SomeElement>
<SomeElement>This is first text of element2
<InnerElement>This is text of inner element2</InnerElement>
This is second text of element2
</SomeElement>
</root>')
,(N'<root>
<SomeElement>This is first text of elementA
<InnerElement>This is text of inner elementA</InnerElement>
This is second text of elementA
</SomeElement>
<SomeElement>This is first text of elementB
<InnerElement>This is text of inner elementB</InnerElement>
This is second text of elementB
</SomeElement>
</root>');
--यह क्वेरी उप-चयन . में से कास्ट आउट के साथ XML को पढ़ेगी . आप CTE
का उपयोग कर सकते हैं इसके बजाय, लेकिन यह केवल वाक्यात्मक चीनी होनी चाहिए...
SELECT se.value(N'(.)[1]','nvarchar(max)') SomeElementsContent
,se.value(N'(InnerElement)[1]','nvarchar(max)') InnerElementsContent
,se.value(N'(./text())[1]','nvarchar(max)') ElementsFirstText
,se.value(N'(./text())[2]','nvarchar(max)') ElementsSecondText
FROM (SELECT CAST(s AS XML) FROM @tbl) AS tbl(TheXml)
CROSS APPLY TheXml.nodes(N'/root/SomeElement') AS A(se);
-- दूसरा भाग टाइप किए गए XML में लिखने और वहां से पढ़ने के लिए तालिका का उपयोग करता है:
DECLARE @tbl2 TABLE(x XML)
INSERT INTO @tbl2
SELECT CAST(s AS XML) FROM @tbl;
SELECT se.value(N'(.)[1]','nvarchar(max)') SomeElementsContent
,se.value(N'(InnerElement)[1]','nvarchar(max)') InnerElementsContent
,se.value(N'(./text())[1]','nvarchar(max)') ElementsFirstText
,se.value(N'(./text())[2]','nvarchar(max)') ElementsSecondText
FROM @tbl2 t2
CROSS APPLY t2.x.nodes(N'/root/SomeElement') AS A(se);
क्यों है /text()
बिना /text()
. से भी तेज ?
यदि आप मेरे उदाहरण को देखें, तो किसी तत्व की सामग्री सब कुछ है ओपनिंग टैग से लेकर क्लोजिंग टैग तक . text()
एक तत्व का फ्लोटिंग टेक्स्ट है इन टैगों के बीच। इसे आप ऊपर दिए गए सेलेक्ट के रिजल्ट में देख सकते हैं। text()
एक पेड़ की संरचना में अलग से संग्रहीत भाग . है वास्तव में (अगला भाग पढ़ें)। इसे लाने के लिए, एक एक-चरणीय-क्रिया है . अन्यथा ओपनिंग टैग और उसके संगत क्लोजिंग टैग के बीच सब कुछ खोजने के लिए एक जटिल संरचना का विश्लेषण करना पड़ता है - भले ही text()
के अलावा और कुछ न हो। ।
मुझे XML को उचित प्रकार में क्यों स्टोर करना चाहिए?
एक्सएमएल सिर्फ कुछ मूर्खतापूर्ण अतिरिक्त पात्रों वाला टेक्स्ट नहीं है! यह एक जटिल संरचना वाला एक दस्तावेज है। XML आपके द्वारा देखे जाने वाले पाठ के रूप में संग्रहीत नहीं है . XML को ट्री स्ट्रक्चर में स्टोर किया जाता है। जब भी आप एक वास्तविक एक्सएमएल में एक एक्सएमएल का प्रतिनिधित्व करने वाली स्ट्रिंग डालते हैं, तो यह बहुत महंगा काम किया जाना चाहिए। जब एक्सएमएल आपको (या कोई अन्य आउटपुट) प्रस्तुत किया जाता है तो प्रतिनिधित्व करने वाला स्ट्रिंग स्क्रैच से (पुनः) बनाया जाता है।
प्री-कास्ट एप्रोच तेज क्यों है
यह अनुमान लगा रहा है...
मेरे उदाहरण में दोनों दृष्टिकोण काफी समान हैं और (लगभग) एक ही निष्पादन योजना की ओर ले जाते हैं।
SQL सर्वर हर उस तरह से काम नहीं करेगा जैसा आप उम्मीद कर सकते हैं। यह एक प्रक्रियात्मक प्रणाली नहीं है जहाँ आप कहते हैं यह करो, इसके बाद करो और बाद में करो! . आप इंजन को बताते हैं कि आप क्या चाहते हैं, और इंजन यह तय करता है कि इसे सबसे अच्छा कैसे किया जाए। और इसके साथ इंजन बहुत अच्छा है!
निष्पादन शुरू होने से पहले, इंजन दृष्टिकोण की लागत का अनुमान लगाने की कोशिश करता है। CONVERT
(या CAST
) बल्कि एक सस्ता ऑपरेशन है। यह हो सकता है, कि इंजन आपकी कॉलों की सूची को कम करने का निर्णय लेता है और प्रत्येक आवश्यकता के लिए कलाकारों को बार-बार करता है, क्योंकि यह सोचता है कि यह व्युत्पन्न तालिका के महंगे निर्माण से सस्ता है...