2010-07-16 15 views
57

मेरे पास एक संग्रहीत प्रक्रिया है जिसमें इनपुट और आउटपुट पैरामीटर का एक गुच्छा है क्योंकि यह एकाधिक तालिकाओं में मान डालने वाला है। कुछ मामलों में संग्रहित प्रो केवल एक ही तालिका में प्रवेश करती है (इनपुट पैरामीटर के आधार पर)। चित्रण करने के लिए यहां एक मजाकिया परिदृश्य है।क्या मेरे पास संग्रहीत प्रक्रिया में वैकल्पिक OUTPUT पैरामीटर हो सकता है?

टेबल्स/डाटा ऑब्जेक्ट्स:

व्यक्ति

Id 
Name 
Address 

नाम

Id 
FirstName 
LastName 

पता

Id 
Country 
City 

कहें कि मेरे पास एक संग्रहित प्रक्रिया है जो किसी व्यक्ति को सम्मिलित करती है। यदि पता मौजूद नहीं है तो मैं इसे डेटाबेस में Address तालिका में नहीं जोड़ूंगा।

इस प्रकार जब मैं संग्रहित प्रक्रिया को कॉल करने के लिए कोड उत्पन्न करता हूं तो मैं Address पैरामीटर जोड़ने को परेशान नहीं करना चाहता हूं। INPUT पैरामीटर के लिए यह ठीक है क्योंकि SQL सर्वर मुझे डिफ़ॉल्ट मानों की आपूर्ति करने की अनुमति देता है। लेकिन OUTPUT पैरामीटर क्या मैं संग्रहीत प्रक्रिया में यह वैकल्पिक तो मैं एक त्रुटि प्राप्त नहीं होता है बनाने के लिए है ... के लिए

प्रक्रिया या समारोह 'Person_InsertPerson' पैरामीटर उम्मीद '@AddressId' है, जो किया गया था आपूर्ति नहीं।

+0

क्या की तरह अपने कोड दिखता है? यही है, कहीं आप इस बात पर शाखा बना रहे हैं कि कोई पता मौजूद है या नहीं। मुझे लगता है कि उस शाखा को देखने के बाद, मेरा सवाल संदिग्ध है, "जब भी कोई पता मौजूद नहीं है, * एक शाखा का उपयोग किए बिना * @ पता आईडी 'के लिए जो कुछ भी आप पास करते हैं, उसमें' न्यूल 'के साथ स्पोक को क्यों न बुलाएं?" – ruffin

उत्तर

90

इनपुट और आउटपुट पैरामीटर दोनों को डिफ़ॉल्ट असाइन किया जा सकता है।इस उदाहरण में:

CREATE PROCEDURE MyTest 
    @Data1 int 
,@Data2 int = 0 
,@Data3 int = null output 

AS 

PRINT @Data1 
PRINT @Data2 
PRINT isnull(@Data3, -1) 

SET @Data3 = @Data3 + 1 

RETURN 0 

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

DECLARE @Output int 

SET @Output = 3 

EXECUTE MyTest 
    @Data1 = 1 
,@Data2 = 2 
,@Data3 = @Output output 

PRINT '---------' 
PRINT @Output 
+2

धन्यवाद! मैं सोच रहा था कि मैं '@var INT OUTPUT = NULL' का उपयोग क्यों नहीं कर सका - वाक्यविन्यास उलझन में है। – trojjer

+0

वास्तव में डिफ़ॉल्ट मान का आह्वान नहीं करता है (आप @output सेट करते हैं) डिफ़ॉल्ट केवल तब सक्रिय होते हैं जब आप कुछ पास नहीं करते हैं, पूर्ण उपचार के लिए मेरा उत्तर देखें। –

1

आप एक संग्रहीत प्रक्रिया और नहीं किसी SQL बयान को क्रियान्वित कर रहे हैं के बाद से, आप संग्रहीत प्रक्रिया करने के लिए अपने एसक्यूएल कमान की कमान प्रकार सेट करना होगा:

cmd.CommandType = CommandType.StoredProcedure; 

here से लिया।

इसके अलावा, एक बार जब आप उस त्रुटि को हटा देते हैं, तो आप अपनी प्रक्रिया में एसक्यूएल के nvl() फ़ंक्शन का उपयोग कर सकते हैं ताकि यह निर्दिष्ट किया जा सके कि जब आप एक पूर्ण मान का सामना करते हैं तो आप क्या प्रदर्शित करना चाहते हैं।

प्रश्न को सही तरीके से संबोधित करने के बारे में क्षमा करें ... आपको गलत समझा जाना चाहिए। यहां nvl का एक उदाहरण दिया गया है, जो मुझे लगता है कि यह थोड़ा बेहतर हो सकता है?

select NVL(supplier_city, 'n/a') 
from suppliers; 

SQL विवरण ऊपर वापसी होगी 'n/a' supplier_city क्षेत्र एक शून्य मान निहित है। अन्यथा, यह supplier_city मान वापस करेगा।

@AddressId int = -1 Output 

AddressId के बाद से पठनीयता के संदर्भ में अपने गरीब की तरह लगता है एक OUTPUT चर के रूप में सख्ती से करना है: जैसे मैं सिर्फ इस तरह के रूप OUTPUT पैरामीटर के लिए एक डिफ़ॉल्ट मान जोड़ सकते हैं

+0

यह सवाल का जवाब नहीं देता है। मैं एंटरप्राइज़ लाइब्रेरी के db.GetStoredProcCommand का उपयोग कर रहा हूं जो मेरे लिए ऐसा करेगा। मैंने इस तरह से कई संग्रहित प्रोसेस बुलाई हैं और वे काफी अच्छी तरह से काम करते हैं। उदाहरण के लिए। कोडडप्रोक को कॉल करने के लिए कोड (डीबी कॉमांड डालनेपर्सन कॉमांड = डीबी.गेटस्टोरप्रोक कॉमांड ("पर्सनल_इंटरर्टसन")) { यह। ऐपेंडइंटर पर्सन पैरामीटर (डीबी, सम्मिलित करेंर्स कॉमांड); db.ExecuteNonQuery (insertPersonCommand, dbTransaction); – Justin

+0

क्षमा करें दोस्त। मैं थोड़ा और प्रासंगिक होने के लिए संपादित किया। – rownage

4

लग रहा है। लेकिन यह काम करता है। यदि आपके पास बेहतर समाधान है तो कृपया मुझे बताएं।

+0

इसमें नुकसान है, पूरा इलाज के लिए मेरा जवाब देखें। –

1

करने पर जोड़ा जा रहा है क्या फिलिप ने कहा:

मैं था मेरी एसक्यूएल सर्वर डेटाबेस में एक संग्रहीत प्रक्रिया है कि की तरह दिखाई देता है:

dbo.<storedProcedure> 
(@current_user char(8) = NULL, 
@current_phase char(3) OUTPUT) 

और मैं अपने .net से बुला रहा था

DataTable dt = SqlClient.ExecuteDataTable(<connectionString>, <storedProcedure>); 

मैं एक System.Data.SqlClient.SqlException हो रही थी: प्रक्रिया या कार्यात्मक निम्नलिखित के रूप में कोड n पैरामीटर '@current_phase' की अपेक्षा करता है, जिसे आपूर्ति नहीं की गई थी।

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

तो यह अब निम्नलिखित के रूप में दिखता है:

dbo.<storedProcedure> 
(@current_user char(8) = NULL, 
@current_phase char(3) = NULL OUTPUT) 
7

आउटपुट मापदंडों और मूलभूत मूल्यों को एक साथ अच्छी तरह से काम नहीं है! यह एसक्यूएल 10.50.1617 (2008 आर 2) से है। इस निर्माण को विश्वास में रखने के लिए बेवकूफ मत बनो अपनी ओर से उस मूल्य पर SET है (जैसे मेरे सहकर्मी ने किया)!

यह "खिलौना" एसपी OUTPUT पैरामीटर मान पूछताछ करता है, भले ही यह डिफ़ॉल्ट मान या NULL है।

CREATE PROCEDURE [dbo].[omgwtf] (@Qty INT, @QtyRetrieved INT = 0 OUTPUT) 
AS 
IF @QtyRetrieved = 0 
BEGIN 
    print 'yay its zero' 
END 
IF @QtyRetrieved is null 
BEGIN 
    print 'wtf its NULL' 
END 
RETURN 

आप OUTPUT के लिए एक गैर-आरंभिकृत मूल्य (अर्थात NULL) में भेजते हैं, तो आप वास्तव में NULL अंदर सपा, और नहीं 0 मिला है। समझ में आता है, उस पैरामीटर के लिए कुछ पारित हो गया।

declare @QR int 
exec [dbo].[omgwtf] 1, @QR output 
print '@QR=' + coalesce(convert(varchar, @QR),'NULL') 

उत्पादन होता है:

wtf its NULL 
@QR=NULL 

हम फोन करने वाले से एक स्पष्ट SET जोड़ देते हैं तो हम पाते हैं:

declare @QR int 
set @QR = 999 
exec [dbo].[omgwtf] 1, @QR output 
print '@QR=' + coalesce(convert(varchar, @QR),'NULL') 

और (unsurprising) उत्पादन:

@QR=999 

फिर, समझ में आता है, एक पैरामीटर पारित किया गया है, और एसपी ने SET पर कोई स्पष्ट कार्रवाई नहीं की है।

(जैसे आप क्या करना चाहिए रहे हैं) में सपा एक SET की OUTPUT पैरामीटर जोड़ें, लेकिन फोन करने वाले से कुछ भी निर्धारित नहीं करते हैं:

ALTER PROCEDURE [dbo].[omgwtf] (@Qty INT, @QtyRetrieved INT = 0 OUTPUT) 
AS 
IF @QtyRetrieved = 0 
BEGIN 
    print 'yay its zero' 
END 
IF @QtyRetrieved is null 
BEGIN 
    print 'wtf its NULL' 
END 
SET @QtyRetrieved = @Qty 
RETURN 

अब जब निष्पादित:

declare @QR int 
exec [dbo].[omgwtf] 1234, @QR output 
print '@QR=' + coalesce(convert(varchar, @QR),'NULL') 

उत्पादन होता है:

wtf its NULL 
@QR=1234 

यह ०१२३६६५८५५४ के लिए "मानक" व्यवहार है एसपी मेंपैरामीटर हैंडलिंग।

अब नाटकीय मोड़ के लिए: के बाद से यह एक OUTPUT के रूप में स्थापित है: करने के लिए "को सक्रिय" डिफ़ॉल्ट मान प्राप्त करने के लिए एक ही रास्ता है, सभी पर OUTPUT पैरामीटर, जो IMHO थोड़ा समझ में आता है पारित नहीं है पैरामीटर, जिसका मतलब कुछ "महत्वपूर्ण" लौटाया जाना चाहिए जिसे एकत्र किया जाना चाहिए।

declare @QR int 
exec [dbo].[omgwtf] 1 
print '@QR=' + coalesce(convert(varchar, @QR),'NULL') 

इस उत्पादन देता है:

yay its zero 
@QR=NULL 

लेकिन इस एस.पी. उत्पादन, शायद की कि सपा के साथ शुरू उद्देश्य पर कब्जा करने में विफल रहता है।

IMHO इस सुविधा संयोजन एक संदिग्ध निर्माण मैं एक कोड गंध (ओफ़्फ़ !!) पर विचार करेगा है

+0

इनपुट के लिए 'OUTPUT' पैरामीटर का उपयोग करने के लिए, terseness (कोड में पुन: उपयोग करने योग्य चर सहित) और अन्य स्पॉक्स सहित, लाभ क्या है? उन इनपुट मानों को "नियमित" पैरामीटर के रूप में क्यों न दें? – ruffin

+1

@ruffin कोई फायदा नहीं है; वैकल्पिक आउटपुट पैरामीटर काम नहीं करते हैं क्योंकि सभी उम्मीद करते हैं, यही कारण है कि मैंने यह जवाब बनाया। –

+0

+1। मुझे लगता है कि मैं बस इतना जोड़ूंगा कि इसका अर्थ है 'आउटपुट' पैरा/सी/के माध्यम से मूल्यों में गुजरना दो कारणों से एक बुरा विचार माना जा सकता है: 1. विचारधारात्मक/कोड गंध, और 2. आपके व्यवहार से व्यावहारिक कारण यहां मिला ¯ \\ _ (ツ) _/¯ – ruffin

संबंधित मुद्दे