Procédure ou fonction! a trop d'arguments spécifiés
je développe ma première procédure stockée dans SQL Server 2008 R2
et besoin de conseils concernant les messages d'erreurs.
procédure ou fonction xxx trop d'arguments spécifiés
que j'obtiens après avoir exécuté la procédure stockée [dbo].[M_UPDATES]
qui appelle une autre procédure stockée appelée etl_M_Update_Promo
.
quand on appelle [dbo].[M_UPDATES]
(code voir ci-dessous) via le clic droit de la souris et " exécuter la procédure stockée’ la requête qui apparaît dans la fenêtre de requête est:
USE [Database_Test]
GO
DECLARE @return_value int
EXEC @return_value = [dbo].[M_UPDATES]
SELECT 'Return Value' = @return_value
GO
La sortie est
Msg 8144, Niveau 16, État 2, la Procédure etl_M_Update_Promo, la Ligne 0
Procédure ou fonction etl_M_Update_Promo a trop d'arguments spécifiés.
QUESTION: que signifie exactement ce message d'erreur, c'est-à-dire où sont trop d'arguments? Comment les identifier?
j'ai trouvé plusieurs threads demandant à propos de ce message d'erreur, mais les codes fournis étaient tous différents du mien (si pas dans une autre langue comme C#
en tout cas). Si aucune réponse n'a résolu le problème de mon SQL
requête (c.-à-d. SPs).
Note: ci-dessous je fournis le code utilisé pour les deux SPs, mais j'ai changé les noms de base de données, les noms de table et les noms de colonne. Alors, s'il vous plaît, ne vous souciez pas des conventions de nommage, ce ne sont que des exemples de noms!
Merci d'avance pour vos conseils et vos réflexions!
(1) Code pour 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 for 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
5 réponses
vous invoquez la fonction avec 2 paramètres (@GenId et @Description):
EXEC etl.etl_M_Update_Promo @GenID, @Description
Cependant, vous avez déclaré à la fonction de prendre 1 argument:
ALTER PROCEDURE [etl].[etl_M_Update_Promo]
@GenId bigint = 0
SQL Server vous dit que [etl_M_Update_Promo]
prend seulement 1 paramètre (@GenId
)
Vous pouvez modifier la procédure pour prendre deux paramètres en spécifiant @Description
.
ALTER PROCEDURE [etl].[etl_M_Update_Promo]
@GenId bigint = 0,
@Description NVARCHAR(50)
AS
.... Rest of your code.
Cette réponse est basée sur le titre et pas le cas dans le post original.
j'ai eu une procédure d'insertion qui a continué à lancer cette erreur ennuyeuse, et même si l'erreur dit, "procédure....a trop d'arguments spécifiés," le fait est que la procédure n'a PAS assez d'arguments.
la table avait une colonne incrémentielle id, et puisqu'elle est incrémentielle, Je n'ai pas pris la peine de l'ajouter comme variable / argument au proc, mais il s'est avéré qu'elle est nécessaire, donc je l'ai ajouté comme @Id et alto comme ils disent...il fonctionne.
Utilisez la commande suivante avant de les définir:
cmd.Parameters.Clear()
en plus de toutes les réponses fournies jusqu'à présent, une autre raison de causer cette exception peut se produire lorsque vous sauvegardez des données d'une liste à une base de données en utilisant ADO.Net.
beaucoup de développeurs utiliseront par erreur for
boucle ou foreach
et laisser le SqlCommand
pour exécuter en dehors de la boucle, pour éviter cela assurez-vous que vous avez comme cet exemple de code par exemple:
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();
}
}
pour ceux qui pourraient avoir le même problème que moi, j'ai eu cette erreur quand le DB que j'utilisais était en fait maître, et non pas la DB que je devrais utiliser.
mettre use [DBName]
en haut de votre script, ou bien changer manuellement la base de données utilisée dans L'interface graphique SQL Server Management Studio.