@Paul के उत्तर से प्रेरित होकर , मैंने कुछ शोध किए और पाया कि यह सच है कि स्टैक स्पेस कॉन्टेक्टेशन की संख्या को सीमित करता है, और यह स्टैक स्पेस उपलब्ध मेमोरी का एक फ़ंक्शन है और इस प्रकार बदलता है, निम्नलिखित दो बिंदु भी सत्य हैं :
- एक बयान में अतिरिक्त संघों को रटने का एक तरीका है, और
- प्रारंभिक स्टैक स्थान सीमा से परे जाने के लिए इस पद्धति का उपयोग करके, एक वास्तविक तार्किक सीमा (जो भिन्न नहीं दिखाई देती है) पाई जा सकती है
सबसे पहले, मैंने पॉल के टेस्ट कोड को स्ट्रिंग को बदलने के लिए अनुकूलित किया:
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = N'
DECLARE @S VARCHAR(MAX), @A VARCHAR(MAX) = ''a'';
SET @S = @A';
SET @SQL += REPLICATE(CONVERT(NVARCHAR(MAX), N' + @A'), 3312) + N';';
-- SET @S = @A + @A + @A...
SET @SQL += N'SELECT DATALENGTH(@S) AS [Chars In @S];';
EXECUTE (@SQL);
इस परीक्षण के साथ, मेरे सबसे बड़े लैपटॉप (केवल 6 जीबी रैम) पर चलने पर मुझे सबसे ज्यादा मिल सकता था:
- 3311 (SQL सर्वर 2017 एक्सप्रेस संस्करण LocalDB (14.0.3006) का उपयोग करके 3333 कुल रिटर्न)
- SQL सर्वर 2012 डेवलपर संस्करण SP4 (KB4018073) (11.0.7001) का उपयोग करके 3512 (कुल 3513 रिटर्न)
8631 त्रुटि होने से पहले ।
इसके बाद, मैंने कोष्ठक का उपयोग करके संघों को समूहीकृत करने की कोशिश की, जैसे कि संचालन संघों के कई समूहों का संघटन होगा। उदाहरण के लिए:
SET @S = (@A + @A + @A + @A) + (@A + @A + @A + @A) + (@A + @A + @A + @A);
यह करते हुए कि मैं 3312 और 3513 चर की पिछली सीमाओं से परे जाने में सक्षम था। अद्यतन कोड है:
DECLARE @SQL VARCHAR(MAX), @Chunk VARCHAR(MAX);
SET @SQL = '
DECLARE @S VARCHAR(MAX), @A VARCHAR(MAX) = ''a'';
SET @S = (@A+@A)';
SET @Chunk = ' + (@A' + REPLICATE(CONVERT(VARCHAR(MAX), '+@A'), 42) + ')';
SET @SQL += REPLICATE(CONVERT(VARCHAR(MAX), @Chunk), 762) + ';';
SET @SQL += 'SELECT DATALENGTH(@S) AS [Chars In @S];';
-- PRINT @SQL; -- for debug
-- SET @S = (@A+@A) + (@A + @A...) + ...
EXECUTE (@SQL);
अधिकतम मान (मेरे लिए) अब 42
पहले के लिए उपयोग करने के लिए हैं REPLICATE
, इस प्रकार प्रति समूह 43 चर का उपयोग करना, और फिर 762
दूसरे के लिए उपयोग करना REPLICATE
, इस प्रकार प्रत्येक 43 चर के 762 समूहों का उपयोग करना है। प्रारंभिक समूह दो चर के साथ हार्ड-कोडित है।
आउटपुट अब दिखाता है कि @S
चर में 32,768 अक्षर हैं । यदि मैं प्रारंभिक समूह को (@A+@A+@A)
केवल के बजाय अद्यतन करता हूं (@A+@A)
, तो मुझे निम्न त्रुटि मिलती है:
Msg 8632, स्तर 17, राज्य 2, लाइन XXXXX
आंतरिक त्रुटि: एक अभिव्यक्ति सेवाओं की सीमा समाप्त हो गई है। कृपया अपनी क्वेरी में संभावित जटिल अभिव्यक्तियों की तलाश करें, और उन्हें सरल बनाने का प्रयास करें।
ध्यान दें कि त्रुटि संख्या पहले की तुलना में भिन्न है। यह अब है: 8632 । और, मेरी एक ही सीमा है कि क्या मैं अपने SQL Server 2012 इंस्टेंस या SQL Server 2017 इंस्टेंस का उपयोग करता हूं।
यह शायद कोई संयोग नहीं है कि यहां ऊपरी सीमा - 32,768 - ( .NET में) की अधिकतम क्षमता है SMALLINT
( Int16
यदि 0
अधिकतम मूल्य 32,767 है, लेकिन कई / अधिकांश प्रोग्रामिंग भाषाओं में सरणियाँ 0-आधारित हैं)।