Procedimiento o función! tiene demasiados argumentos especificados


Estoy desarrollando mi primer procedimiento almacenado en SQL Server 2008 R2 y necesito asesoramiento sobre el mensaje de errores.

Procedimiento o función xxx demasiados argumentos especificados

Que obtengo después de ejecutar el procedimiento almacenado [dbo].[M_UPDATES] que llama a otro procedimiento almacenado llamado etl_M_Update_Promo.

Cuando se llama a [dbo].[M_UPDATES] (código ver más abajo) mediante un clic con el botón derecho del ratón y 'Ejecutar procedimiento almacenado', la consulta que aparece en la ventana de consulta es:

USE [Database_Test]
GO

DECLARE @return_value int

EXEC    @return_value = [dbo].[M_UPDATES]

SELECT  'Return Value' = @return_value

GO

La salida es

Msg 8144, Nivel 16, Estado 2, Procedimiento etl_M_Update_Promo, Línea 0
El procedimiento o función etl_M_Update_Promo tiene demasiados argumentos especificados.

PREGUNTA : ¿Qué significa exactamente este mensaje de error, es decir, dónde hay demasiados argumentos? Cómo identificarlos?

Encontré varios hilos preguntando por este mensaje de error, pero los códigos proporcionados eran todos diferentes a los míos (si no en otro idioma como C# de todos modos). Así que ninguno de los las respuestas solucionaron el problema de mi consulta SQL (es decir, SPs).

Nota: a continuación proporciono el código utilizado para los dos SPs, pero cambié los nombres de la base de datos, los nombres de las tablas y los nombres de las columnas. Así que, por favor, no se preocupe por las convenciones de nombres, estos son solo nombres de ejemplo!

Gracias de antemano por cualquier consejo y pensamientos!

(1) Código para 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) Código para 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
Author: Darren, 2013-06-25

5 answers

Invoca la función con 2 parámetros (@GenId y @Description):

EXEC etl.etl_M_Update_Promo @GenID, @Description

Sin embargo, ha declarado que la función toma 1 argumento:

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

SQL Server le dice que [etl_M_Update_Promo] solo toma 1 parámetro (@GenId)

Puede modificar el procedimiento para tomar dos parámetros especificando @Description.

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

.... Rest of your code.
 31
Author: Darren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-25 08:37:57

Esta respuesta se basa en el título y no en el caso específico del post original.

Tuve un procedimiento de inserción que siguió lanzando este molesto error, y a pesar de que el error dice, "procedimiento....tiene demasiados argumentos especificados, " el hecho es que el procedimiento no tenía suficientes argumentos.

La tabla tenía una columna de id incremental, y como es incremental, no me molesté en agregarla como variable / argumento al proc, pero resultó que es necesaria, por lo que añadido como @Id y viola como ellos say...it funciona.

 2
Author: usefulBee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-10 20:23:19

Utilice el siguiente comando antes de definirlos:

cmd.Parameters.Clear()
 2
Author: FEOL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-22 02:22:03

Además de todas las respuestas proporcionadas hasta ahora, otra razón para causar esta excepción puede ocurrir cuando está guardando datos de la lista a la base de datos utilizando ADO.Net.

Muchos desarrolladores utilizarán erróneamente for bucle o foreach y dejarán el SqlCommand para ejecutar fuera del bucle, para evitar que asegúrese de que tiene como este ejemplo de código por ejemplo:

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();
        }
    }
 0
Author: Ashraf Abusada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-30 22:10:56

Para aquellos que podrían tener el mismo problema que yo, obtuve este error cuando la base de datos que estaba usando era en realidad master, y no la base de datos que debería usar.

Simplemente coloque use [DBName] en la parte superior de su script, o cambie manualmente la base de datos en uso en la interfaz gráfica de usuario de SQL Server Management Studio.

 0
Author: Ray Lionfang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-20 02:35:06