2013-06-25 12 views
24

Ich entwickle meine allererste gespeicherte Prozedur in SQL Server 2008 R2 und brauche Beratung bezüglich der Fehlermeldung.Vorgehensweise oder Funktion !!! hat zu viele Argumente angegeben

Prozedur oder Funktion xxx zu viele Argumente angegeben

, die ich erhalten, nachdem die gespeicherte Prozedur [dbo].[M_UPDATES] ausgeführt werden, die eine andere gespeicherte Prozedur etl_M_Update_Promo genannt aufruft.

Beim Aufruf [dbo].[M_UPDATES] (Code siehe unten) über die rechte Maustaste klicken und 'Ausführen gespeicherte Prozedur' die Abfrage, die in dem Abfrage-Fenster erscheint, ist:

USE [Database_Test] 
GO 

DECLARE @return_value int 

EXEC @return_value = [dbo].[M_UPDATES] 

SELECT 'Return Value' = @return_value 

GO 

Der Ausgang

ist

Msg 8144, Ebene 16, Status 2, Prozedur etl_M_Update_Promo, Zeile 0
Prozedur oder Funktion etl_M_Update_Promo hat zu viele Argumente angegeben.

FRAGE: Was bedeutet diese Fehlermeldung genau bedeuten, das heißt, wo zu viele Argumente sind? Wie identifiziere ich sie?

Ich habe mehrere Threads gefunden, die nach dieser Fehlermeldung fragen, aber die bereitgestellten Codes waren alle anders als meine (wenn nicht in einer anderen Sprache wie C#). So löste keine der Antworten das Problem meiner Anfrage (d. H. SPs).

Hinweis: unten stelle ich den Code für die beiden SPs zur Verfügung, aber ich änderte die Datenbanknamen, Tabellennamen und Spaltennamen. Also, bitte, mach dir keine Gedanken über Namenskonventionen, das sind nur Beispielnamen!

Vielen Dank im Voraus für jede Beratung und Gedanken!

(1)-Code für 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)-Code für 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 

Antwort

30

Sie die Funktion mit 2 Parametern aufrufen (@GenId und @BESCHREIBUNG):

EXEC etl.etl_M_Update_Promo @GenID, @Description 

jedoch die Funktion deklariert haben 1 Argument zu nehmen:

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

SQL Server sagt Ihnen, dass [etl_M_Update_Promo] dauert nur 1 Parameter (@GenId)

Sie das Verfahren ändern, kann durch Angabe @Description zwei Parameter zu übernehmen.

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

.... Rest of your code. 
+1

Excellent! Dies funktioniert nach dem Löschen von @ Beschreibung NVARCHAR (50) aus dem Abschnitt zu deklarieren. Danke, dass du so schnell und klar reagierst! – user2006697

+1

@Darren Gibt es einen Mechanismus, um unerwartete Parameter zu ignorieren? –

+2

@AliAdlavaran fügen Sie ihnen einen Standardwert – CiucaS

1

Diese Antwort bezieht sich auf den Titel und nicht auf den speziellen Fall im Originaltext.

Ich hatte eine Einfügungsprozedur, die diesen lästigen Fehler warf, und obwohl der Fehler sagt, "Prozedur .... hat zu viele Argumente angegeben", die Tatsache ist, dass die Prozedur nicht genug Argumente hatte.

Die Tabelle hatte eine inkrementelle ID-Spalte, und da es inkrementell ist, habe ich nicht die Mühe gemacht, es als Variable/Argument zum Proc hinzuzufügen, aber es stellte sich heraus, dass es benötigt wird, also habe ich es als @Id hinzugefügt und Viola wie sie sagen ... es funktioniert.

+0

Ich hatte das gleiche. Die @ID wurde mit einem Standardwert = 0 zur Prozedur hinzugefügt, aber das VBA-Objekt verwendet sie nicht in ihrem Aufruf, noch wird sie im INSERT verwendet, aber ja, es funktioniert jetzt gut. Lustigerweise, wenn ich die EXEC in SQL ausführte, war es in Ordnung, aber nicht, wenn ich von meinem VBA-Projekt aufgerufen wurde. Muss ein Fehler sein! – CarloC

1

den folgenden Befehl verwenden, bevor sie zu definieren:

cmd.Parameters.Clear() 
0

Neben allen bisher gab Antworten, ein weiterer Grund, diese Ausnahme zu veranlassen, kann passieren, wenn Sie Daten aus Liste Datenbank speichern ADO.Net mit .

Viele Entwickler werden fälschlicherweise verwenden for Schleife oder foreach und lassen Sie die SqlCommand außerhalb der Schleife auszuführen, dass sicher, zu vermeiden, dass Sie dieses Codebeispiel zum Beispiel haben:

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(); 
     } 
    } 
Verwandte Themen