TVP को READONLY क्यों होना चाहिए, और अन्य प्रकार के पैरामीटर को READONLY क्यों नहीं किया जा सकता है


19

इस ब्लॉग के मापदंडों के अनुसार एक फ़ंक्शन या एक संग्रहीत प्रक्रिया अनिवार्य रूप से पास-बाय-वैल्यू है यदि वे OUTPUTपैरामीटर नहीं हैं, और अनिवार्य रूप से पास-बाय-संदर्भ के सुरक्षित संस्करण के रूप में माना जाता है यदि वे OUTPUTपैरामीटर हैं।

पहले मुझे लगा कि TVP को घोषित करने का लक्ष्य READONLYडेवलपर्स को स्पष्ट रूप से संकेत देना था कि TVP को एक OUTPUTपैरामीटर के रूप में इस्तेमाल नहीं किया जा सकता है , लेकिन वहाँ अधिक होना चाहिए क्योंकि हम गैर-TVP को घोषित नहीं कर सकते READONLY। उदाहरण के लिए निम्नलिखित विफल रहता है:

create procedure [dbo].[test]
@a int readonly
as
    select @a

एमएसजी 346, स्तर 15, राज्य 1, प्रक्रिया परीक्षण
पैरामीटर "@ ए" को केवल इसलिए घोषित नहीं किया जा सकता है क्योंकि यह एक टेबल-वैल्यू पैरामीटर नहीं है।

  1. चूंकि आंकड़े टीवीपी पर संग्रहीत नहीं हैं, इसलिए डीएमएल संचालन को रोकने के पीछे तर्क क्या है?
  2. क्या यह OUTPUTकिसी कारण से टीवीपी के मापदंडों के नहीं होने से संबंधित है?

जवाबों:


19

स्पष्टीकरण इस तरह के लिंक से बंधे हुए प्रतीत होता है: क) इस प्रश्न में उल्लेखित ब्लॉग से विस्तार नहीं किया गया है, ख) टीवीपीएस फिटिंग की व्यावहारिकता कैसे मापदंडों को हमेशा अंदर और बाहर, सी) और प्रकृति में पारित किया गया है। तालिका चर की।

  1. लिंक किए गए ब्लॉग पोस्ट में मौजूद अनुपलब्ध विवरण बिल्कुल वैसा ही है, जिसमें स्टोर्ड प्रोसीजर और फ़ंक्शंस में वेरिएबल्स को पास और आउट किया जाता है (जो "पास-ऑफ़-रेफ़रेंस के सुरक्षित संस्करण के प्रश्न से संबंधित है, यदि वे OUTPUT पैरामीटर हैं") :

    TSQL संग्रहीत प्रक्रियाओं और कार्यों के लिए मापदंडों को पारित करने के लिए एक कॉपी-इन / कॉपी-आउट शब्दार्थ का उपयोग करता है ...।

    ... जब संग्रहित किए गए अधिप्राप्ति को निष्पादित करने में त्रुटि होती है (बिना किसी त्रुटि के) एक कॉपी-आउट बनाई जाती है, जो किसी भी परिवर्तन के साथ पारित पैरामीटर को अद्यतन करता है जो कि संग्रहीत खरीद में किए गए थे।

    इस दृष्टिकोण का वास्तविक लाभ त्रुटि मामले में है। यदि संग्रहीत कार्यविधि के निष्पादन के बीच में कोई त्रुटि होती है, तो मापदंडों में किए गए कोई भी परिवर्तन कॉलर को वापस प्रचारित नहीं करेंगे।

    यदि OUTPUT कीवर्ड मौजूद नहीं है तो कोई भी कॉपी-आउट नहीं किया जाता है।

    नीचे की रेखा:
    संग्रहीत प्रोम के पैरामीटर कभी भी संग्रहित खरीद के आंशिक निष्पादन को प्रतिबिंबित नहीं करते हैं यदि यह एक त्रुटि का सामना करना पड़ा।

    इस पहेली का भाग 1 यह है कि मापदंडों को हमेशा "मूल्य से" पारित किया जाता है। और, यह केवल तब होता है जब पैरामीटर को चिह्नित किया जाता है OUTPUT और संग्रहीत प्रक्रिया सफलतापूर्वक पूरी होती है कि वर्तमान मूल्य वास्तव में वापस भेजा जाता है। यदि OUTPUTमान वास्तव में "संदर्भ द्वारा" पारित किए गए थे, तो उस चर की याद में स्थान के लिए सूचक वह चीज़ होगी जो पारित हो गई थी, न कि स्वयं मूल्य। और यदि आप पॉइंटर (यानी मेमोरी एड्रेस) में पास होते हैं तो किए गए किसी भी बदलाव को तुरंत परिलक्षित किया जाता है, भले ही संग्रहीत प्रक्रिया की अगली पंक्ति में त्रुटि हो और यह निष्पादन को रोक देता है।

    भाग 1 को सम्‍मिलित करने के लिए: चर मान हमेशा कॉपी किए जाते हैं; उन्हें उनके स्मृति पते से संदर्भित नहीं किया जाता है।

  2. भाग 1 को ध्यान में रखते हुए, हमेशा परिवर्तनशील मूल्यों को कॉपी करने की नीति संसाधन मुद्दों को जन्म दे सकती है जब चर को पारित किया जा रहा है। मैं यह देखने के लिए ब्लॉब प्रकार नियंत्रित किया जाता है परीक्षण नहीं किया ( VARCHAR(MAX), NVARCHAR(MAX), VARBINARY(MAX), XML, और उन है कि अब और नहीं किया जाना चाहिए: TEXT, NTEXT, और IMAGE), लेकिन यह सुरक्षित कहना है कि डेटा के किसी भी तालिका पारित किया जा रहा में काफी बड़ी हो सकता है। यह उन लोगों के लिए समझ में आता है जो टीवीपी फीचर को विकसित करने के लिए एक सच्चे "पास-बाय-रेफरेंस" की इच्छा रखते हैं, ताकि उनके कूल नए फीचर को एक स्वस्थ संख्या प्रणाली को नष्ट करने से रोका जा सके (अर्थात अधिक स्केलेबल अप्रोच चाहते हैं)। जैसा कि आप प्रलेखन में देख सकते हैं कि उन्होंने क्या किया:

    Transact-SQL इनपुट डेटा की एक प्रतिलिपि बनाने से बचने के लिए संदर्भ द्वारा दिनचर्या के लिए टेबल-मूल्यवान पैरामीटर पास करता है।

    इसके अलावा, यह स्मृति प्रबंधन चिंता एक नई अवधारणा नहीं थी क्योंकि यह SQLCLR API में पाया जा सकता है जो SQL Server 2005 (TVPs SQL सर्वर 2008 में पेश किया गया था) में पेश किया गया था। SQLCLR कोड में पासिंग NVARCHARऔर VARBINARYडेटा (यानी एक SQLCLR असेंबली के भीतर .NET विधियों पर इनपुट पैरामीटर), आपके पास SqlStringया तो SqlBinaryक्रमशः उपयोग करके "मूल्य द्वारा" दृष्टिकोण के साथ जाने का विकल्प है , या आप "संदर्भ द्वारा" के साथ जा सकते हैं " SqlCharsया तो या SqlBytesक्रमशः का उपयोग करके दृष्टिकोण । । SqlCharsऔर SqlBytesप्रकार .NET सीएलआर में डेटा की पूरी स्ट्रीमिंग के लिए अनुमति देते हैं, ताकि आप पूरे 200 एमबी (अप करने के लिए 2 जीबी, दाईं ओर) मान कॉपी करने के विरोध में बड़े मानों के छोटे हिस्से खींच सकें।

    भाग 2 की गणना करने के लिए: टीवीपी, अपने स्वभाव से, बहुत अधिक मेमोरी (और इसलिए खराब होने वाले प्रदर्शन) का उपभोग करने की प्रवृत्ति होगी यदि "हमेशा मूल्य को कॉपी करें" मॉडल के भीतर रहें। इसलिए TVP एक "संदर्भ द्वारा पास" एक सच्चा काम करते हैं।

  3. अंतिम टुकड़ा यही कारण है कि भाग 2 मायने रखता है: क्यों एक टीवीपी में वास्तव में "संदर्भ से" गुजरता है, इसके बजाय इसकी प्रतिलिपि बनाने से कुछ भी बदल जाता है। और इसका उत्तर उस डिज़ाइन लक्ष्य द्वारा दिया गया है जो भाग 1 के लिए आधार है: संग्रहीत कार्यविधियाँ जो सफलतापूर्वक पूरी नहीं होती हैं, किसी भी तरह से, इनपुट मापदंडों में से किसी में भी परिवर्तन नहीं होना चाहिए, चाहे वे चिह्नित हों OUTPUTया नहीं। डीएमएल संचालन की अनुमति देने से टीवीपी के मूल्य पर तत्काल प्रभाव पड़ेगा क्योंकि यह कॉलिंग संदर्भ में मौजूद है (संदर्भ से गुजरने के बाद से आप उस चीज़ को बदल रहे हैं जिसे पारित किया गया था, जो पारित नहीं किया गया था की एक प्रति)।

    अब, कोई, कहीं न कहीं, इस बिंदु पर शायद उनके मॉनिटर से बात कर रहा है, "ठीक है, बस TVP मापदंडों में किए गए किसी भी बदलाव को वापस करने के लिए एक स्वचालित सुविधा में निर्माण करें यदि कोई भी संग्रहीत प्रक्रिया में पारित किया गया था। इतना शीघ्र नही। यह वह जगह है जहाँ टेबल वेरिएबल्स की प्रकृति आती है: टेबल वेरिएबल्स में किए गए परिवर्तन लेन-देन से बाध्य नहीं हैं! इसलिए परिवर्तनों को वापस लाने का कोई तरीका नहीं है। और वास्तव में, यह एक ट्रिक है जिसका उपयोग किसी लेन-देन के भीतर उत्पन्न जानकारी को बचाने के लिए किया जाता है यदि रोलबैक :-) होने की आवश्यकता होती है।

    भाग 3 को सम्‍मिलित करने के लिए: टेबल-वेरिएबल त्रुटि के मामले में उनके लिए किए गए "पूर्ववत" परिवर्तनों की अनुमति नहीं देता है, जिसके कारण संग्रहित प्रक्रिया निरस्त हो जाती है। और यह उन मापदंडों के डिजाइन लक्ष्य का उल्लंघन करता है जो कभी भी आंशिक निष्पादन (भाग 1) को प्रतिबिंबित नहीं करते हैं।

एर्गो:READONLY टीवीपी पर डीएमएल संचालन को रोकने के लिए कीवर्ड की आवश्यकता होती है क्योंकि वे टेबल चर हैं जो वास्तव में "संदर्भ द्वारा" पारित किए जाते हैं, और इसलिए उनके लिए कोई भी संशोधन तुरंत परिलक्षित होगा, भले ही संग्रहीत प्रक्रिया एक त्रुटि का सामना करती है, और कोई भी नहीं है इसे रोकने के अन्य तरीके।

इसके अतिरिक्त, अन्य डेटाटाइप्स के पैरामीटर का उपयोग नहीं किया जा सकता है READONLYक्योंकि वे पहले से ही जो कुछ भी पारित किया गया था, उसकी प्रतियां हैं, और इसलिए यह पहले से संरक्षित न होने वाली किसी भी चीज़ की रक्षा नहीं करेगा। यही कारण है, और जिस तरह से अन्य डेटाटाइप्स के मापदंडों को पढ़ने-लिखने का इरादा था, इसलिए यह संभव है कि उस एपीआई को बदलने के लिए अब और भी अधिक काम होगा जिसमें केवल-पढ़ने की अवधारणा शामिल है।


बहुत विस्तृत विवरण। धन्यवाद। तो एक संग्रहीत प्रक्रिया के साथ एक पारित तालिका चर (या तो उपयोगकर्ता TVP TYPEचर या क DECLARE x as TABLE (...)) को संशोधित करने का कोई तरीका नहीं है ? क्या मैं इसे कर सकता हूं, एक बड़े स्मृति पदचिह्न के साथ, एक फ़ंक्शन के साथ set @tvp = myfunction(@tvp)यदि मेरे फ़ंक्शन का RETURNSमान टीवीपी प्रकार के समान DDL के साथ एक तालिका है?
एमपाग

@ चंपक धन्यवाद। एक TVP है एक मेज चर, वहाँ कोई अंतर नहीं है। आप प्रकार में पास नहीं होते हैं, आप एक प्रकार से या स्पष्ट स्कीमा घोषणा से बनाए गए तालिका चर में पास होते हैं। इसके अलावा, आप SETएक तालिका चर नहीं कर सकते , कम से कम ऐसा नहीं है जिसके बारे में मुझे जानकारी है। और यहां तक ​​कि अगर आप कर सकते हैं: ए) आप =ऑपरेटर के माध्यम से सेट किए गए परिणाम तक नहीं पहुंच सकते हैं , और बी) टीवीपी को अभी भी चिह्नित किया गया है READONLY, इसलिए इसे सेट करना उल्लंघन होगा। बस सामग्री को एक टेम्‍प टेबल या दूसरे टेबल वैरिएबल में डंप करें जो आप प्रोक के भीतर बनाते हैं।
सोलोमन रटज़की

एक बार फिर धन्यवाद। मैंने अनिवार्य रूप से एक अस्थायी तालिका दृष्टिकोण का उपयोग करने का फैसला किया है।
एमपाग

5

मार्टिन ने स्मिथ के सवाल पर एक टिप्पणी से उत्पन्न सामुदायिक विकी का जवाब दिया

इसके लिए एक सक्रिय कनेक्ट आइटम (Erland Sommarskog द्वारा प्रस्तुत) है:

जब एसपी एक-दूसरे को कॉल करते हैं तो टेबल के मापदंडों को आराम से पढ़ें

Microsoft द्वारा अब तक की गई एकमात्र प्रतिक्रिया कहती है (जोर दिया गया):

इस पर प्रतिक्रिया के लिए धन्यवाद। हमें बड़ी संख्या में ग्राहकों से समान प्रतिक्रिया मिली है। पढ़ने / लिखने के लिए मूल्यवान मानों को रखने के लिए SQL इंजन पक्ष के साथ-साथ क्लाइंट प्रोटोकॉल पर काफी काम शामिल है। समय / संसाधन बाधाओं के साथ-साथ अन्य प्राथमिकताओं के कारण, हम SQL Server 2008 रिलीज़ के भाग के रूप में इस काम को नहीं ले पाएंगे। हालाँकि, हमने इस समस्या की जाँच की है और इसे SQL सर्वर की अगली रिलीज़ के हिस्से के रूप में संबोधित करने के लिए हमारे रडार में मजबूती से है। हम यहां की प्रतिक्रिया की सराहना और स्वागत करते हैं।

श्रीनी आचार्य
वरिष्ठ कार्यक्रम प्रबंधक
एसक्यूएल सर्वर रिलेशनल इंजन

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.