存储过程或函数需要未提供的参数
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;
添加后,我的应用程序运行正常。
【讨论】:
以上是关于存储过程或函数需要未提供的参数的主要内容,如果未能解决你的问题,请参考以下文章
过程或函数“过程名称”需要一个未提供的参数“参数名称”很少发生
过程或函数“uspExportGetMailinfoTest”需要参数“@CUSTOMER”,但未提供该参数。我错过了啥?