Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

nvarchar संघटन / अनुक्रमणिका / nvarchar(अधिकतम) अकथनीय व्यवहार

TLDR; पंक्तियों में तार जोड़ने के लिए यह एक दस्तावेज/समर्थित दृष्टिकोण नहीं है। यह कभी-कभी काम करता है लेकिन कभी-कभी विफल भी हो जाता है क्योंकि यह निर्भर करता है कि आपको कौन सी निष्पादन योजना मिलती है।

इसके बजाय निम्नलिखित गारंटीकृत दृष्टिकोणों में से किसी एक का उपयोग करें

एसक्यूएल सर्वर 2017+

SELECT @a = STRING_AGG([msg], '') WITHIN GROUP (ORDER BY [priority] ASC)
FROM bla
where   autofix = 0

एसक्यूएल सर्वर 2005+

SELECT @a = (SELECT [msg] + ''
             FROM   bla
             WHERE  autofix = 0
             ORDER  BY [priority] ASC
             FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)') 

पृष्ठभूमि

VanDerNorth द्वारा पहले से लिंक किए गए KB आलेख में यह पंक्ति शामिल है

<ब्लॉकक्वॉट>

एक समग्र संयोजन क्वेरी के लिए सही व्यवहार अपरिभाषित है।

लेकिन फिर एक समाधान प्रदान करके पानी को थोड़ा गंदा कर देता है जो यह इंगित करता है कि नियतात्मक व्यवहार संभव है।

<ब्लॉकक्वॉट>

समग्र संयोजन क्वेरी से अपेक्षित परिणाम प्राप्त करने के लिए, किसी भी ट्रांजैक्ट-एसक्यूएल फ़ंक्शन या अभिव्यक्ति को ORDER BY क्लॉज के बजाय चयन सूची में कॉलम पर लागू करें।

आपकी समस्यात्मक क्वेरी ORDER BY . के कॉलम पर कोई एक्सप्रेशन लागू नहीं करती है खंड।

2005 का आलेख SQL सर्वर में गारंटी देता है... बताता है

<ब्लॉकक्वॉट>

पश्च संगतता कारणों के लिए, SQL सर्वर शीर्ष-अधिकांश दायरे में SELECT @p =@p + 1 ... ORDER BY प्रकार के असाइनमेंट के लिए समर्थन प्रदान करता है।

उन योजनाओं में जहां संघनन कार्य करता है जैसा कि आपने अभिव्यक्ति के साथ गणना स्केलर की अपेक्षा की थी [Expr1003] = Scalar Operator([@x]+[Expr1004]) क्रम से ऊपर दिखाई देता है।

योजना में जहां यह काम करने में विफल रहता है, कंप्यूट स्केलर सॉर्ट के नीचे दिखाई देता है। जैसा कि 2006 से इस कनेक्ट आइटम में बताया गया है जब अभिव्यक्ति @x = @x + [msg] प्रत्येक पंक्ति के लिए मूल्यांकन किए गए क्रम के नीचे दिखाई देता है लेकिन सभी मूल्यांकन @x के पूर्व असाइनमेंट मान का उपयोग करके समाप्त होते हैं . 2006 से इसी तरह के एक अन्य कनेक्ट आइटम में Microsoft की प्रतिक्रिया ने समस्या को "ठीक" करने की बात कही।

इस मुद्दे पर बाद के सभी कनेक्ट आइटम पर Microsoft प्रतिक्रिया (और कई हैं) बताती है कि इसकी गारंटी नहीं है

उदाहरण 1

<ब्लॉकक्वॉट>

हम समवर्ती प्रश्नों की शुद्धता पर कोई गारंटी नहीं देते हैं (जैसे विशिष्ट क्रम में डेटा पुनर्प्राप्ति के साथ परिवर्तनीय असाइनमेंट का उपयोग करना)। क्वेरी आउटपुट SQL Server 2008 में बदल सकता है, जो योजना की पसंद, तालिकाओं में डेटा आदि पर निर्भर करता है। आपको इस पर लगातार काम नहीं करना चाहिए, भले ही सिंटैक्स आपको एक SELECT स्टेटमेंट लिखने की अनुमति देता है जो ऑर्डर की गई पंक्तियों की पुनर्प्राप्ति को परिवर्तनीय असाइनमेंट के साथ मिलाता है।

उदाहरण 2

<ब्लॉकक्वॉट>

आप जो व्यवहार देख रहे हैं वह डिज़ाइन द्वारा है। ORDER BY क्लॉज वाले प्रश्नों में असाइनमेंट ऑपरेशंस (इस उदाहरण में संयोजन) का उपयोग करना अपरिभाषित व्यवहार है। यह क्वेरी योजना में परिवर्तन के कारण रिलीज़ से रिलीज़ या किसी विशेष सर्वर संस्करण के भीतर भी बदल सकता है। आप इस व्यवहार पर भरोसा नहीं कर सकते, भले ही वर्कअराउंड हों। अधिक विवरण के लिए नीचे KB आलेख देखें:
http://support.microsoft.com/kb/287515 केवल गारंटीकृत तंत्र निम्नलिखित हैं:

  1. पंक्तियों के माध्यम से विशिष्ट क्रम में लूप करने के लिए कर्सर का उपयोग करें और मानों को संयोजित करें
  2. सम्मिलित मान उत्पन्न करने के लिए ORDER BY के साथ xml क्वेरी के लिए उपयोग करें
  3. सीएलआर एग्रीगेट का उपयोग करें (यह ORDER BY क्लॉज के साथ काम नहीं करेगा)

उदाहरण 3

<ब्लॉकक्वॉट>

आप जो व्यवहार देख रहे हैं वह वास्तव में डिज़ाइन द्वारा है। इसे एसक्यूएल के साथ सेट-मैनिपुलेशन भाषा होने के साथ करना है। SELECTlist में सभी एक्सप्रेशन (और इसमें असाइनमेंट भी शामिल हैं) प्रत्येक आउटपुट पंक्ति के लिए बिल्कुल एक बार निष्पादित होने की गारंटी नहीं है। वास्तव में, SQL queryoptimizer उन्हें यथासंभव कम से कम निष्पादित करने के लिए कठिन प्रयास करता है। यह अपेक्षित परिणाम देगा जब आप तालिकाओं में कुछ डेटा के आधार पर चर के मूल्य की गणना कर रहे हैं, लेकिन जब आप जो मान निर्दिष्ट कर रहे हैं वह उसी चर के पिछले मान पर निर्भर करता है, तो परिणाम काफी अप्रत्याशित हो सकते हैं। यदि क्वेरी ऑप्टिमाइज़र अभिव्यक्ति को क्वेरी ट्री में किसी भिन्न स्थान पर ले जाता है, तो इसका मूल्यांकन कम बार हो सकता है (या केवल एक बार, जैसा कि आपके किसी एक उदाहरण में है)। यही कारण है कि हम समग्र मूल्यों की गणना के लिए "पुनरावृत्ति" प्रकार के असाइनमेंट का उपयोग करने की अनुशंसा नहीं करते हैं। हम पाते हैं कि एक्सएमएल-आधारित वर्कअराउंड ... आमतौर पर ग्राहकों के लिए अच्छा काम करते हैं

उदाहरण 4

<ब्लॉकक्वॉट>

ORDER BY के बिना भी, हम इस बात की गारंटी नहीं देते हैं कि @var =@var + किसी भी स्टेटमेंट के लिए समवर्ती मान उत्पन्न करेगा जो कई पंक्तियों को प्रभावित करता है। क्वेरी निष्पादन के दौरान अभिव्यक्ति के दाहिने हाथ का मूल्यांकन या तो एक या कई बार किया जा सकता है और जैसा कि मैंने कहा व्यवहार योजना पर निर्भर है।

उदाहरण 5

<ब्लॉकक्वॉट>

सेलेक्ट स्टेटमेंट के साथ वेरिएबल असाइनमेंट एक मालिकाना सिंटैक्स (केवल टी-एसक्यूएल) है जहां व्यवहार अपरिभाषित है या योजना निर्भर है यदि कई पंक्तियों का उत्पादन किया जाता है। यदि आपको स्ट्रिंग संयोजन करने की आवश्यकता है, तो SQLCLR समुच्चय या XML क्वेरी आधारित संयोजन या अन्य संबंधपरक विधियों का उपयोग करें।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. प्रति समूह पहली पंक्ति का चयन

  2. SQL सर्वर में डायनामिक पिवट टेबल

  3. Xamarin.Forms में सीधे एक Sql सर्वर डेटाबेस तक पहुँचना

  4. किसी अन्य तालिका में डेटा से गणना कॉलम अपडेट करें

  5. इन 3 युक्तियों के साथ SQL सर्वर प्रदर्शन ट्यूनिंग में सुधार करें