存储过程或函数需要未提供的参数

Posted

技术标签:

【中文标题】存储过程或函数需要未提供的参数【英文标题】:Stored procedure or function expects parameter which is not supplied 【发布时间】:2013-10-31 10:13:33 【问题描述】:

我正在尝试通过调用存储过程将数据插入 SQL Server 数据库,但出现错误

过程或函数“SHOWuser”需要参数“@userID”,但未提供。

我的存储过程称为SHOWuser。我已经仔细检查过了,没有遗漏任何参数。

我的代码是:

public void SHOWuser(string userName, string password, string emailAddress, List<int> preferences)

        SqlConnection dbcon = new SqlConnection(conn);

        try
         
            SqlCommand cmd = new SqlCommand();

            cmd.Connection = dbcon;
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            cmd.CommandText = "SHOWuser";

            cmd.Parameters.AddWithValue("@userName", userName);
            cmd.Parameters.AddWithValue("@password", password);
            cmd.Parameters.AddWithValue("@emailAddress", emailAddress);

            dbcon.Open();

            int i = Convert.ToInt32(cmd.ExecuteScalar());

            cmd.Parameters.Clear();
            cmd.CommandText = "tbl_pref";

            foreach (int preference in preferences)
            
                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@userID", Convert.ToInt32(i));
                cmd.Parameters.AddWithValue("@preferenceID", Convert.ToInt32(preference));

                cmd.ExecuteNonQuery();
            
        
        catch (Exception)
        
            throw;
        
        finally
        
            dbcon.Close();
        

存储过程是:

ALTER PROCEDURE [dbo].[SHOWuser]
(
    @userName varchar(50),
    @password nvarchar(50),
    @emailAddress nvarchar(50)
)
AS
BEGIN
    INSERT INTO tbl_user(userName, password, emailAddress) 
    VALUES (@userName, @password, @emailAddress)

    SELECT
        tbl_user.userID, tbl_user.userName,
        tbl_user.password, tbl_user.emailAddress, 
        STUFF((SELECT ',' + preferenceName 
               FROM tbl_pref_master
               INNER JOIN tbl_preferences ON tbl_pref_master.preferenceID = tbl_preferences.preferenceID
               WHERE tbl_preferences.userID = tbl_user.userID
               FOR XML PATH ('')), 1, 1, ' ' ) AS Preferences
    FROM
        tbl_user

    SELECT SCOPE_IDENTITY();
END

这是在同一函数中使用的第二个存储过程tbl_pref

ALTER PROCEDURE [dbo].[tbl_pref]
    @userID int,
    @preferenceID int
AS
BEGIN
    INSERT INTO tbl_preferences(userID, preferenceID) 
    VALUES (@userID, @preferenceID)
END

【问题讨论】:

错误非常明显。 sproc 需要一个名为 UserID 的参数。您的调用代码未提供任何名为 UserID 的参数。 这里的preferenceName是一个复选框列表,我已经在其中输入了数据库中的值。 PL 帮助。 但是 userID 是一个自动生成的列。 您似乎没有在代码中传递 UserID 的参数。它是一个身份列吗? @user2920046 - 在 proc 定义中仍然需要它,并且在代码中缺失。这就是您看到错误消息的原因。 【参考方案1】:

在我的情况下,即使正确提供了所有参数值但未指定命令类型,我也收到此异常:

cmd.CommandType = System.Data.CommandType.StoredProcedure;

上面的问题显然不是这种情况,但是这种情况下的异常描述不是很清楚,所以我决定具体说明一下。

【讨论】:

我想知道为什么异常指定缺少参数?可能是因为CommandType 没有设置为StoredProcedure,所以它不会发送任何添加到SqlCommand 的参数? 谢谢!你救了我! @Alex Krotnyi 您的回答帮助我意识到在我的情况下这是预期的输出参数。我忘记了 [[cmd.Parameters.Add("@OutParamNameHere", SqlDbType.Int).Direction = ParameterDirection.Output;]] 后面的 .net 代码中的这段代码 哇,多么不直观的错误!一直在用头撞我的桌子,试图弄清楚为什么它说我的“输出”参数没有定义。谢谢!【参考方案2】:

我昨天遇到了这个问题,但这里没有一个解决方案完全有效,但它们确实为我指明了正确的方向。

我们的应用程序是一个用 C# 编写的工作流工具,并且过于简化,在数据库中有几个存储过程,以及每个存储过程使用的每个参数的元数据表(名称、顺序、数据类型、大小、等),允许我们根据需要创建尽可能多的新存储过程,而无需更改 C#。

对问题的分析表明我们的代码在SqlCommand对象上设置了所有正确的参数,但是一旦执行,它就会抛出与OP得到的相同的错误。

进一步分析显示,一些参数的值为null。因此,我必须得出结论,SqlCommand 对象会忽略其 .Parameters 集合中值为 null 的任何 SqlParameter 对象。

我发现这个问题有两种解决方案。

    在我们的存储过程中,为每个参数指定一个默认值,例如从@Parameter int@Parameter int = NULL(或其他需要的默认值)。

    在我们生成单个SqlParameter 对象的代码中,分配DBNull.Value 而不是null,其中预期值是SQL NULL 就可以了。

原来的编码人员已经继续前进,代码最初是在考虑解决方案 1 的情况下编写的,并且在权衡了两者的好处之后,我想我会坚持使用解决方案 1。为 a 指定默认值要容易得多编写时特定的存储过程,而不是代码中定义的始终为NULL

希望对某人有所帮助。

【讨论】:

这就是发生在我身上的事情......我将 null 作为参数之一传递 完美解决了我的问题。我的存储过程有 100 多个参数,我无法弄清楚为什么在提供所有参数时会出现此错误。非常感谢 我有 25 个参数,全部提供,并且由于测试数据集不同而在各种参数上出现此错误。似乎不一致的结果是随机的空值。使用 solution 1 成功了。【参考方案3】:

您的存储过程需要 5 个参数作为输入

@userID int, 
@userName varchar(50), 
@password nvarchar(50), 
@emailAddress nvarchar(50), 
@preferenceName varchar(20) 

所以你应该在这个 SP 调用中添加所有 5 个参数:

    cmd.CommandText = "SHOWuser";
    cmd.Parameters.AddWithValue("@userID",userID);
    cmd.Parameters.AddWithValue("@userName", userName);
    cmd.Parameters.AddWithValue("@password", password);
    cmd.Parameters.AddWithValue("@emailAddress", emailAddress);
    cmd.Parameters.AddWithValue("@preferenceName", preferences);
    dbcon.Open();

PS:不清楚这些参数的用途。您不在 SP 正文中使用这些参数,因此您的 SP 应如下所示:

ALTER PROCEDURE [dbo].[SHOWuser] AS BEGIN ..... END

【讨论】:

请再次查看代码。我已经编辑了代码和存储过程。现在出现的错误类似于 ERROR: object reference not set to an instance of an object。 @user2920046 如果您已经从 STORED PROCEDURE 中删除了参数,那么您也应该从您的代码中删除所有 cmd.Parameters.AddWithValue 我没有删除任何内容。 userName、password 和 emailAddress 值将存储在用户输入的数据库中,而preferenceName 将由用户从我已经在数据库中输入值的复选框列表中选择。 @user2920046 现在您已将第一个存储过程从 SELECT 更改为 INSERT,因此您应该将 int i = Convert.ToInt32(cmd.ExecuteScalar()); 更改为 cmd.ExecuteNonQuery(); 在第一个存储过程中,我添加了插入查询。它包含选择和插入查询。【参考方案4】:

在我的情况下,即使我在 C# 端正确设置了输出参数,但我发现我忘记为存储过程的输出参数提供默认值

ALTER PROCEDURE [dbo].[test]
(
                @UserID int,
                @ReturnValue int = 0 output --Previously I had @ReturnValue int output
)

【讨论】:

【参考方案5】:

在我的例子中,它返回一个输出参数并且没有返回任何值。 于是改成了

param.Direction = ParameterDirection.Output;
command.ExecuteScalar();

然后它抛出大小错误。所以也必须设置大小

SqlParameter param = new SqlParameter("@Name",SqlDbType.NVarChar);
param.Size = 10;

【讨论】:

【参考方案6】:

在我的例子中,我传递了所有参数,但我的代码中的一个参数传递了字符串的空值。

例如:cmd.Parameters.AddWithValue("@userName", userName);

在上述情况下,如果 userName 的数据类型是字符串,我将 userName 传递为 null。

【讨论】:

【参考方案7】:

研究后发现我没有具体说明

command.CommandType = System.Data.CommandType.StoredProcedure;

添加后,我的应用程序运行正常。

【讨论】:

以上是关于存储过程或函数需要未提供的参数的主要内容,如果未能解决你的问题,请参考以下文章

过程或函数“SP”需要参数“@param”,但未提供该参数

过程或函数“过程名称”需要一个未提供的参数“参数名称”很少发生

C#使用输出变量调用存储过程时出错,未提供参数

存储过程参数名称和实体框架

SQL Server:执行存储过程问题

过程或函数“uspExportGetMailinfoTest”需要参数“@CUSTOMER”,但未提供该参数。我错过了啥?