2012-06-05 8 views
42

में संग्रहित प्रक्रिया आउटपुट पैरामीटर का उपयोग करना मुझे एक SQL सर्वर संग्रहीत प्रक्रिया से आउटपुट पैरामीटर को C# चर में वापस करने में समस्या आ रही है। मैंने इस विषय से संबंधित अन्य पोस्ट पढ़ी हैं, न केवल यहां बल्कि अन्य साइटों पर, और मैं इसे काम नहीं कर सकता। मेरे पास वर्तमान में क्या है। वर्तमान में मैं वापस आने वाले मूल्य को मुद्रित करने की कोशिश कर रहा हूं। निम्नलिखित कोड एक शून्य मान देता है। जो मैं वापस करने की कोशिश कर रहा हूं वह प्राथमिक कुंजी है। मैंने @@IDENTITY और SCOPE_INDENTITY() (यानी SET @NewId = SCOPE_IDENTITY()) का उपयोग करने का प्रयास किया है।सी #

संग्रहित प्रक्रिया:

CREATE PROCEDURE usp_InsertContract 
    @ContractNumber varchar(7), 

    @NewId int OUTPUT 
AS 
BEGIN 

    INSERT into [dbo].[Contracts] (ContractNumber) 
     VALUES (@ContractNumber) 

    Select @NewId = Id From [dbo].[Contracts] where ContractNumber = @ContractNumber 
END 

डेटाबेस खुलने:

pvCommand = new SqlCommand("usp_InsertContract", pvConnection); 

pvCommand.Transaction = pvTransaction; 
pvCommand.CommandType = CommandType.StoredProcedure;  

pvCommand.Parameters.Clear(); 
pvCommand.Parameters.Add(new SqlParameter("@ContractNumber", contractNumber)); 

SqlParameter pvNewId = new SqlParameter(); 
pvNewId.ParameterName = "@NewId"; 
pvNewId.DbType = DbType.Int32; 
pvNewId.Direction = ParameterDirection.Output; 
pvCommand.Parameters.Add(pvNewId); 

try 
{ 
    sqlRows = pvCommand.ExecuteNonQuery(); 

    if (sqlRows > 0) 
     Debug.Print("New Id Inserted = ", 
      pvCommand.Parameters["@NewId"].Value.ToString()); 
    } 
    catch (Exception e) 
    { 
     Debug.Print("Insert Exception Type: {0}", e.GetType()); 
     Debug.Print(" Message: {0}", e.Message); 
    } 
} 
+1

मैं एक ही तालिका की आवश्यकता के बजाय SCOPE_IDENTITY() का भी उपयोग करता हूं, और यदि आपको एक आउटपुट var को असाइन करते समय 'क्वेरी कई परिणाम लौटा सकता है' त्रुटि प्राप्त होती है। – JMC

+0

क्या मैं इसे करने के लिए सेट कमांड का उपयोग करता हूं?SET NewId = SCOPE_IDENTITY()? मैंने चयन कथन को निम्नलिखित के साथ बदल दिया है ... SET @NewId = SCOPE_IDENTITY() और मुझे अभी भी एक शून्य मान वापस प्राप्त होता है। – Gary

+0

बेशक आप पुष्टि कर सकते हैं कि नया रिकॉर्ड वास्तव में डाला गया है, है ना? क्या आप अपना सी # कोड (कनेक्शन खोलना, कमांड इत्यादि का निर्माण ..) दिखा सकते हैं – Steve

उत्तर

1

संग्रहित प्रक्रिया .........

:

pvConnectionString = "Server = Desktop-PC\\SQLEXPRESS; Database = PVDatabase; User ID = sa; 
    PASSWORD = *******; Trusted_Connection = True;"; 

try 
{ 
    pvConnection = new SqlConnection(pvConnectionString); 
    pvConnection.Open(); 
} 
catch (Exception e) 
{ 
    databaseError = true; 
} 

आदेश निष्पादित

CREATE PROCEDURE usp_InsertContract 
    @ContractNumber varchar(7) 
AS 
BEGIN 

    INSERT into [dbo].[Contracts] (ContractNumber) 
     VALUES (@ContractNumber) 

    SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY] 
END 

सी #

pvCommand.CommandType = CommandType.StoredProcedure; 

pvCommand.Parameters.Clear(); 
pvCommand.Parameters.Add(new SqlParameter("@ContractNumber", contractNumber)); 
object uniqueId; 
int id; 
    try 
    { 
    uniqueId = pvCommand.ExecuteScalar(); 
    id = Convert.ToInt32(uniqueId); 
    } 
    catch (Exception e) 
    { 
     Debug.Print(" Message: {0}", e.Message); 
    } 
} 

संपादित करें: "मुझे अभी तक एक DBNull मूल्य .... वस्तु अन्य प्रकार की DBNull से ढाला नहीं जा सकता मिलता है। मैं कल इसे फिर से ले जाऊंगा। मैं अपने अन्य काम के लिए रवाना हूँ, "

मेरा मानना ​​है कि अपने एसक्यूएल तालिका के आईडी कॉलम एक पहचान स्तंभ नहीं है।

enter image description here

+0

लेकिन यह सवाल नहीं है कि क्यों नई आईडी के लिए आउटपुट पैरामीटर शून्य हो जाता है। 'ExecuteScalar' के साथ आप एक वापसी मान पुनर्प्राप्त कर सकते हैं आउटपुट पैरामीटर नहीं। –

+0

जब मैं यह परिवर्तन करता हूं तो मुझे निम्न त्रुटि भी मिलती है ... ऑब्जेक्ट संदर्भ किसी ऑब्जेक्ट के उदाहरण पर सेट नहीं होता है। – Gary

+0

Thats क्योंकि पैरामीटर को SCOPE_IDENTITY कहा जाता है, एसक्यूएल में; सी # अभी भी @ContractNumber नामक पैरामीटर की तलाश में है। –

82

मैं थोड़ा अपने संग्रहीत प्रक्रिया संशोधित (उपयोग करने के लिए SCOPE_IDENTITY) है और यह इस तरह दिखता है:

CREATE PROCEDURE usp_InsertContract 
    @ContractNumber varchar(7), 
    @NewId int OUTPUT 
AS 
BEGIN 
    INSERT INTO [dbo].[Contracts] (ContractNumber) 
    VALUES (@ContractNumber) 

    SELECT @NewId = SCOPE_IDENTITY() 
END 

मैं इस कोशिश की और यह (संशोधित संग्रहीत प्रक्रिया के साथ) ठीक काम करता है:

012,
// define connection and command, in using blocks to ensure disposal 
using(SqlConnection conn = new SqlConnection(pvConnectionString)) 
using(SqlCommand cmd = new SqlCommand("dbo.usp_InsertContract", conn)) 
{ 
    cmd.CommandType = CommandType.StoredProcedure; 

    // set up the parameters 
    cmd.Parameters.Add("@ContractNumber", SqlDbType.VarChar, 7); 
    cmd.Parameters.Add("@NewId", SqlDbType.Int).Direction = ParameterDirection.Output; 

    // set parameter values 
    cmd.Parameters["@ContractNumber"].Value = contractNumber; 

    // open connection and execute stored procedure 
    conn.Open(); 
    cmd.ExecuteNonQuery(); 

    // read output value from @NewId 
    int contractID = Convert.ToInt32(cmd.Parameters["@NewId"].Value); 
    conn.Close(); 
} 

क्या यह आपके पर्यावरण में भी काम करता है? मैं नहीं कह सकता कि आपका मूल कोड क्यों काम नहीं करेगा - लेकिन जब मैं इसे यहां करता हूं, वीएस -2010 और एसक्यूएल सर्वर 2008 आर 2, यह सिर्फ बेकार ढंग से काम करता है ....

यदि आपको कोई मूल्य वापस नहीं मिलता है - तो मुझे संदेह है कि आपकी तालिका Contracts पर वास्तव में IDENTITY संपत्ति के साथ कोई कॉलम नहीं हो सकता है।

+3

+1 लेने के लिए आपको बहुत बहुत धन्यवाद! –

+6

धन्यवाद! मैं इसके जवाब देने में आपके समय की सराहना करता हूं कि हम वर्षों में इसे गुगल कर रहे हैं। :-) –

+0

@marc_s अगर वर्कर आउटपुट का आकार अज्ञात है तो उस समस्या से निपटने के लिए कैसे करें। – Gunner

3

संग्रहीत प्रक्रिया को बदलने से पहले कृपया जांचें कि आपके वर्तमान का आउटपुट क्या है। SQL सर्वर प्रबंधन में निम्न चलाएं:

DECLARE @NewId int 
EXEC @return_value = [dbo].[usp_InsertContract] 
      N'Gary', 
      @NewId OUTPUT 
SELECT @NewId 

देखें कि यह क्या लौटाता है। यह आपको कुछ संकेत दे सकता है कि आपका आउट param क्यों भरा नहीं है।

+0

यह सिर्फ एक उत्तर के रूप में काम करता है, लेकिन शायद एक टिप्पणी होनी चाहिए, हालांकि मैं इसे एकाधिक @ चरित्र उपयोग (यहां तक ​​कि मोड को अस्वीकार कर दिया गया है) के कारण इसे परिवर्तित नहीं कर सकता है और मुझे इसे बनाने के लिए इसे संपादित करने पर परेशान नहीं किया जा सकता काम। :) – Kev

0

अपने सी # कोड में, आप कमांड के लिए लेनदेन का उपयोग कर रहे हैं। बस लेनदेन करें और उसके बाद आपके पैरामीटर मान को एक्सेस करें, आपको मूल्य मिलेगा। मेरे लिए काम किया। :)