टी-एसक्यूएल - डिफ़ॉल्ट मापदंडों के साथ कार्य करता है


155

मेरे पास यह स्क्रिप्ट है:

CREATE FUNCTION dbo.CheckIfSFExists(@param1 INT, @param2 BIT = 1 )
RETURNS BIT
AS
BEGIN
    IF EXISTS ( bla bla bla )
        RETURN 1;
    RETURN 0;
END
GO

मैं इसे इस तरीके से एक प्रक्रिया में उपयोग करना चाहता हूं:

IF dbo.CheckIfSFExists( 23 ) = 0
    SET @retValue = 'bla bla bla';

लेकिन मुझे त्रुटि मिलती है:

प्रक्रिया या कार्य dbo.CheckIfSFExists के लिए तर्कों की अपर्याप्त संख्या की आपूर्ति की गई थी।

यह काम क्यों नहीं करता है?

जवाबों:


227

आपको इसे इस तरह से कॉल करना होगा

SELECT dbo.CheckIfSFExists(23, default)

से टेकनेट :

जब फ़ंक्शन के एक पैरामीटर का डिफ़ॉल्ट मान होता है, तो डिफ़ॉल्ट मान को प्राप्त करने के लिए फ़ंक्शन को कॉल करने पर कीवर्ड DEFAULT को निर्दिष्ट किया जाना चाहिए। यह व्यवहार संग्रहीत कार्यविधियों में डिफ़ॉल्ट मानों के साथ मापदंडों का उपयोग करने से भिन्न होता है जिसमें पैरामीटर को छोड़ने से डिफ़ॉल्ट मान भी निकलता है। इस व्यवहार के लिए अपवाद है जब EXECUTE कथन का उपयोग करके किसी स्केलर फ़ंक्शन को लागू करना। EXECUTE का उपयोग करते समय, DEFAULT कीवर्ड की आवश्यकता नहीं होती है।


80
यह देखकर मैं निराश हूं। मुझे defaultयहां अवधारणा का लाभ नहीं मिल रहा है ... मुझे अब सभी स्थानों पर जाने और बदलने की आवश्यकता है।
LCJ

8
@ लिजो, आपको अभी भी प्रत्येक कॉल पर अपने ठोस डिफ़ॉल्ट मूल्य की नकल नहीं करने का लाभ मिलता है।
Frédéric

9
जैसा कि हमें ओवरले करने की अनुमति नहीं है, और "डिफ़ॉल्ट" इस प्रकार सीमित प्रयोज्य है, अक्सर सबसे अच्छा दृष्टिकोण अतिरिक्त प्रत्यय के साथ एक प्रत्यय (यहाँ CheckIfSFExistsEX कहते हैं) और मूल फ़ंक्शन को बदलने के साथ एक नया विस्तारित संस्करण बनाना होगा। "डिफ़ॉल्ट" पैरामीटर के साथ विस्तारित संस्करण को कॉल करना। इस तरह से सभी मौजूदा कोड काम करते हैं, और आपके पास बनाए रखने के लिए केवल एक जगह है।
एसके राहन

39

आप इसे तीन तरीकों से कह सकते हैं - मापदंडों के साथ, DEFAULT के साथ और EXECUTE के माध्यम से

SET NOCOUNT ON;

DECLARE
@Table  SYSNAME = 'YourTable',
@Schema SYSNAME = 'dbo',
@Rows   INT;

SELECT dbo.TableRowCount( @Table, @Schema )

SELECT dbo.TableRowCount( @Table, DEFAULT )

EXECUTE @Rows = dbo.TableRowCount @Table

SELECT @Rows

11
DEFAULTचयन में कीवर्ड की आवश्यकता क्यों है , लेकिन निष्पादन में छोड़ा जा सकता है? यह बेकार है: / उम्मीद है कि यह किसी दिन तय हो जाएगा।
मिस्सीयू

@ मिस्सी, यह कुछ ऐसा नहीं है जिसे "निश्चित" करने की आवश्यकता है। वह डिजाइन द्वारा है। मैंने हर तर्क को निर्दिष्ट किए बिना एक फ़ंक्शन को कॉल करने में सक्षम होने के लिए एक "आदर्श" लक्ष्य का दृष्टिकोण करने के लिए बहुत सारे विकल्प पढ़े, लेकिन मुझे इसकी स्पष्ट व्याख्या नहीं दिखाई दी कि इसकी आवश्यकता क्यों है। कोड स्पष्ट होना चाहिए और इसे प्राप्त करने के लिए एक रणनीति यह होनी चाहिए कि कोडर को हमेशा यह पता होना चाहिए कि "अरे, आप एक फ़ंक्शन को कॉल कर रहे हैं जो ऐसा नहीं है और यह अन्य तर्क है, जो डिफ़ॉल्ट मान रखने के लिए होता है। यह मत भूलना। डिफ़ॉल्ट मानों को बदल दिया जाना चाहिए "। तो, IMO, यह एक अच्छी "बुरी बात" है।
गुस्तावो पिंसार्ड

16

उपयोगकर्ता परिभाषित कार्यों के साथ, आपको प्रत्येक पैरामीटर को घोषित करना होगा, भले ही उनका डिफ़ॉल्ट मान हो।

निम्नलिखित सफलतापूर्वक निष्पादित होगा:

IF dbo.CheckIfSFExists( 23, default ) = 0
    SET @retValue = 'bla bla bla;

-1

इस समस्या का एक तरीका आउटपुट पैरामीटर के साथ संग्रहीत प्रक्रियाओं का उपयोग करना है।

exec sp_mysprocname @returnvalue आउटपुट, @firstparam = 1, @ secondparam = 2

वे मान जो आप डिफ़ॉल्ट रूप से संग्रहीत कार्यविधि में निर्धारित डिफ़ॉल्ट के पास नहीं जाते हैं। और आप अपने आउटपुट चर से परिणाम प्राप्त कर सकते हैं।


1
अपने कार्य को एक संग्रहीत प्रक्रिया में बदलना सामान्य रूप से अच्छा समाधान नहीं है, क्योंकि एक संग्रहीत प्रक्रिया को क्वेरी के भीतर से नहीं बुलाया जा सकता है, लेकिन एक फ़ंक्शन कर सकता है।
ब्लेड

हालांकि, कोड के सभी ब्लॉक को क्वेरी के भीतर से कॉल करने की आवश्यकता नहीं है। यह दिखाया गया है कि sql में फ़ंक्शन के लिए डिफ़ॉल्ट मानों को संभालने का एक अच्छा तरीका नहीं है (डिफ़ॉल्ट कीवर्ड का उपयोग मूल्य जोड़ने के रूप में लगभग उतना ही काम है)। यह एक अच्छा सामान्य समाधान नहीं है, लेकिन यह कुछ उपयोग मामलों में बहुत अच्छा काम करता है।
जेरेमी गुएन्थर

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

1
संग्रहित प्रक्रियाओं का उपयोग करने का अर्थ किसी फ़ंक्शन का उपयोग करने के बजाय उनका उपयोग करना नहीं है - इसका मतलब यह हो सकता है कि किसी फ़ंक्शन के आसपास संग्रहीत प्रक्रिया का उपयोग रैपर के रूप में किया जाए। मैं अक्सर इस तकनीक का उपयोग करता हूं; डिफ़ॉल्ट कीवर्ड अब proc के अंदर छिपे हुए हैं। मुझे लगता है कि यह विचार ठीक है। यह मुझे और अधिक जटिल चूक करने देता है यदि मैं चाहता हूं - फ़ंक्शन से अलग, जिसे अधिक शुद्ध स्थिति में छोड़ा जा सकता है।
जे ब्रायन मूल्य
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.