2013-06-25 8 views
24

निर्दिष्ट कई तर्क हैं ISQL Server 2008 R2 में मेरी पहली संग्रहीत प्रक्रिया विकसित कर रहा है और त्रुटियों के संदेश से संबंधित सलाह की आवश्यकता है।प्रक्रिया या कार्य !!!

प्रक्रिया या समारोह xxx भी कई तर्क

जो मैं संग्रहीत प्रक्रिया [dbo].[M_UPDATES] कि etl_M_Update_Promo नामक एक और संग्रहीत प्रक्रिया कॉल को क्रियान्वित करने के बाद मिलता है निर्दिष्ट।

जब बुला [dbo].[M_UPDATES] के माध्यम से (कोड नीचे देखें) राइट माउस क्लिक करें और क्वेरी कि प्रश्न-विंडो में दिखाई देता है 'संग्रहीत प्रक्रिया निष्पादित':

USE [Database_Test] 
GO 

DECLARE @return_value int 

EXEC @return_value = [dbo].[M_UPDATES] 

SELECT 'Return Value' = @return_value 

GO 

उत्पादन

है

संदेश 8144, स्तर 16, राज्य 2, प्रक्रिया etl_M_Update_Promo, रेखा 0
प्रक्रिया या कार्य etl_M_Update_Promo में बहुत से तर्क निर्दिष्ट हैं।

प्रश्न: क्या यह त्रुटि संदेश वास्तव में क्या मतलब है, यानि कि जहां भी कई तर्क हैं? उन्हें कैसे पहचानें?

मुझे इस त्रुटि संदेश के बारे में पूछने वाले कई धागे मिले, लेकिन प्रदान किए गए कोड मेरे लिए अलग थे (यदि किसी अन्य भाषा में C# वैसे भी नहीं है)। इसलिए किसी भी उत्तर ने मेरे क्वेरी (यानी एसपी) की समस्या को हल किया।

नोट: नीचे मैं दो एसपी के लिए इस्तेमाल किया गया कोड प्रदान करता हूं, लेकिन मैंने डेटाबेस नाम, तालिका नाम और कॉलम नाम बदल दिए। तो, कृपया, सम्मेलन नामकरण के बारे में चिंतित न हों, ये केवल उदाहरण नाम हैं!

किसी भी सलाह और विचारों के लिए अग्रिम धन्यवाद!

(1) कोड के लिए SP1 [dbo]। [M_UPDATES]

USE [Database_Test] 
GO 

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[ M_UPDATES] AS 
declare @GenID bigint 
declare @Description nvarchar(50) 

Set @GenID = SCOPE_IDENTITY() 
Set @Description = 'M Update' 

BEGIN 
EXEC etl.etl_M_Update_Promo @GenID, @Description 
END 

GO 

(2) कोड SP2 [etl_M_Update_Promo]

USE [Database_Test] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [etl].[etl_M_Update_Promo] 
@GenId bigint = 0 
as 

declare @start datetime = getdate() 
declare @Process varchar (100) = 'Update_Promo' 
declare @SummeryOfTable TABLE (Change varchar (20)) 
declare @Description nvarchar(50) 
declare @ErrorNo int 
, @ErrorMsg varchar (max) 
declare @Inserts int = 0 
, @Updates int = 0 
, @Deleted int = 0 
, @OwnGenId bit = 0 

begin try 


if @GenId = 0 begin 
INSERT INTO Logging.dbo.ETL_Gen (Starttime) 
VALUES (@start) 

SET @GenId = SCOPE_IDENTITY() 
SET @OwnGenId = 1 
end 


MERGE [Database_Test].[dbo].[Promo] AS TARGET 
USING OPENQUERY(M ,'select * from m.PROMO') AS SOURCE 
ON (TARGET.[E] = SOURCE.[E]) 


WHEN MATCHED AND TARGET.[A] <> SOURCE.[A] 
    OR TARGET.[B] <> SOURCE.[B] 
    OR TARGET.[C] <> SOURCE.[C] 
    THEN 
UPDATE SET TARGET.[A] = SOURCE.[A] 
    ,TARGET.[B] = SOURCE.[B] 
    , TARGET.[C] = SOURCE.[c] 

WHEN NOT MATCHED BY TARGET THEN 
INSERT ([E] 
    ,[A] 
    ,[B] 
    ,[C] 
    ,[D] 
    ,[F] 
    ,[G] 
    ,[H] 
    ,[I] 
    ,[J] 
    ,[K] 
    ,[L] 
) 
VALUES (SOURCE.[E] 
    ,SOURCE.[A] 
    ,SOURCE.[B] 
    ,SOURCE.[C] 
    ,SOURCE.[D] 
    ,SOURCE.[F] 
    ,SOURCE.[G] 
    ,SOURCE.[H] 
    ,SOURCE.[I] 
    ,SOURCE.[J] 
    ,SOURCE.[K] 
    ,SOURCE.[L] 
) 

OUTPUT $ACTION INTO @SummeryOfTable; 


with cte as (
SELECT 
Change, 
COUNT(*) AS CountPerChange 
FROM @SummeryOfTable 
GROUP BY Change 
) 

SELECT 
@Inserts = 
    CASE Change 
     WHEN 'INSERT' THEN CountPerChange ELSE @Inserts 
    END, 
@Updates = 
    CASE Change 
     WHEN 'UPDATE' THEN CountPerChange ELSE @Updates 
    END, 
@Deleted = 
    CASE Change 
     WHEN 'DELETE' THEN CountPerChange ELSE @Deleted 
    END 
FROM cte 


INSERT INTO Logging.dbo.ETL_log (GenID, Startdate, Enddate, Process, Message, Inserts, Updates, Deleted,Description) 
VALUES (@GenId, @start, GETDATE(), @Process, 'ETL succeded', @Inserts, @Updates,  @Deleted,@Description) 


if @OwnGenId = 1 
UPDATE Logging.dbo.ETL_Gen 
SET Endtime = GETDATE() 
WHERE ID = @GenId 

end try 
begin catch 

SET @ErrorNo = ERROR_NUMBER() 
SET @ErrorMsg = ERROR_MESSAGE() 

INSERT INTO Logging.dbo.ETL_Log (GenId, Startdate, Enddate, Process, Message, ErrorNo, Description) 
VALUES (@GenId, @start, GETDATE(), @Process, @ErrorMsg, @ErrorNo,@Description) 


end catch 
GO 

उत्तर

30

आप समारोह 2 मानकों के साथ (आह्वान के लिए @GenId और @Description):

EXEC etl.etl_M_Update_Promo @GenID, @Description 

हालांकि आप समारोह घोषणा की है 1 तर्क लेने के लिए:

012,
ALTER PROCEDURE [etl].[etl_M_Update_Promo] 
    @GenId bigint = 0 

एसक्यूएल सर्वर आपको बता रहा है कि [etl_M_Update_Promo] केवल 1 पैरामीटर (@GenId)

आप प्रक्रिया को बदल सकते हैं @Description निर्दिष्ट करके दो पैरामीटर लेने के लिए ले जाता है।

ALTER PROCEDURE [etl].[etl_M_Update_Promo] 
    @GenId bigint = 0, 
    @Description NVARCHAR(50) 
AS 

.... Rest of your code. 
+1

बहुत बढ़िया! यह घोषणा अनुभाग से @ डिस्क्रिप्शन NVARCHAR (50) हटाने के बाद काम करता है। इतनी तेजी से और स्पष्ट प्रतिक्रिया देने के लिए धन्यवाद! – user2006697

+1

@Darren अप्रत्याशित पैरामीटर को अनदेखा करने के लिए एक तंत्र है? –

+2

@AliAdlavaran उन्हें एक डिफ़ॉल्ट मान जोड़ें – CiucaS

1

यह उत्तर शीर्षक पर आधारित है और मूल पोस्ट में विशिष्ट मामला नहीं है।

मेरे पास एक ऐसी प्रक्रिया है जो इस कष्टप्रद त्रुटि को फेंकती रही है, और फिर भी त्रुटि कहती है, "प्रक्रिया .... में बहुत से तर्क निर्दिष्ट हैं," तथ्य यह है कि प्रक्रिया में पर्याप्त तर्क नहीं थे।

तालिका में वृद्धिशील आईडी कॉलम था, और चूंकि यह वृद्धिशील है, इसलिए मैंने इसे प्रो में एक चर/तर्क के रूप में जोड़ने के लिए परेशान नहीं किया, लेकिन यह पता चला कि इसकी आवश्यकता है, इसलिए मैंने इसे @Id के रूप में जोड़ा और व्हायोला जैसे वे कहते हैं ... यह काम करता है।

+0

मेरे पास वही था। प्रक्रिया में डिफ़ॉल्ट = 0 के साथ @ID जोड़ा गया है लेकिन वीबीए ऑब्जेक्ट इसे अपने कॉल में उपयोग नहीं कर रहा है और न ही इसे INSERT में उपयोग किया जा रहा है लेकिन हाँ, यह ठीक काम करता है। काफी हद तक, जब मैं एसक्यूएल में EXEC चला गया तो यह ठीक था, लेकिन जब मेरी वीबीए परियोजना से नहीं बुलाया गया था। एक बग होना है! – CarloC

1

उन्हें परिभाषित करने से पहले निम्न आदेश का उपयोग:

cmd.Parameters.Clear() 
0

सभी अब तक प्रदान की जवाब के अलावा, इस अपवाद के कारण के लिए एक और कारण हो सकता है जब आप ADO.Net का उपयोग कर डेटाबेस के लिए सूची से डेटा की बचत कर रहे ।

कई डेवलपर्स गलती से for पाश या foreach का उपयोग करें और सुनिश्चित करें कि आप कि उदाहरण के लिए इस कोड नमूने की तरह है कि कर SqlCommand छोड़ पाश बाहर निष्पादित करने के लिए, से बचने के लिए होगा:

public static void Save(List<myClass> listMyClass) 
    { 
     using (var Scope = new System.Transactions.TransactionScope()) 
     { 
      if (listMyClass.Count > 0) 
      { 
       for (int i = 0; i < listMyClass.Count; i++) 
       { 
        SqlCommand cmd = new SqlCommand("dbo.SP_SaveChanges", myConnection); 
        cmd.CommandType = CommandType.StoredProcedure; 
        cmd.Parameters.Clear(); 

        cmd.Parameters.AddWithValue("@ID", listMyClass[i].ID); 
        cmd.Parameters.AddWithValue("@FirstName", listMyClass[i].FirstName); 
        cmd.Parameters.AddWithValue("@LastName", listMyClass[i].LastName); 

        try 
        { 
         myConnection.Open(); 
         cmd.ExecuteNonQuery(); 
        } 
        catch (SqlException sqe) 
        { 
         throw new Exception(sqe.Message); 
        } 
        catch (Exception ex) 
        { 
         throw new Exception(ex.Message); 
        } 
        finally 
        { 
         myConnection.Close(); 
        } 
       } 
      } 
      else 
      { 
       throw new Exception("List is empty"); 
      } 

      Scope.Complete(); 
     } 
    } 
संबंधित मुद्दे