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

时间:2013-10-31 10:13:33

标签: sql sql-server stored-procedures

我试图通过调用存储过程将数据插入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

6 个答案:

答案 0 :(得分:142)

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

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

在上面的问题中显然不是这种情况,但在这种情况下异常描述不是很清楚,所以我决定指定。

答案 1 :(得分:32)

我昨天遇到过这个问题,但这里的解决方案都没有完全奏效,但他们确实指出了我正确的方向。

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

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

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

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

  1. 在我们的存储过程中,为每个参数指定一个默认值,因此从@Parameter int@Parameter int = NULL(或其他一些默认值)。

  2. 在我们生成单个SqlParameter对象的代码中,指定DBNull.Value而非null,其中预期值为SQL NULL。 / p>

  3. 原始编码器已经开始了,代码最初是用解决方案1编写的,并且已经权衡了两者的好处,我想我会坚持使用解决方案1.为指定一个默认值要容易得多编写时的特定存储过程,而不是代码中定义的NULL

    希望能有所帮助。

答案 2 :(得分:9)

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

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

因此,您应该将所有5个参数添加到此SP调用中:

    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

答案 3 :(得分:4)

在我的情况下,我得到了输出参数的错误,即使我在C#端正确设置我发现我忘了给存储过程输出参数的默认值

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

答案 4 :(得分:3)

就我而言,它返回了一个输出参数,并没有返回任何值 所以改成了

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

然后它抛出尺寸错误。所以不得不设置大小

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

答案 5 :(得分:0)

在我的情况下,我正在传递所有参数,但是我的代码中的一个参数正在传递字符串的空值。

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

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