【问题标题】:'Procedure or function expects parameter, which was not supplied' error“程序或函数需要参数,但未提供”错误
【发布时间】:2014-12-09 05:23:53
【问题描述】:

我的服务中有一个方法正在调用 SQL Server 数据库中的存储过程,但出现错误:

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

当我在 SQL Server Mgmt Studio 中执行我的存储过程时,它可以工作,所以我很确定是我的 C# 方法导致了错误。我的代码如下所示:

public class Invite
{
        public Int64 InviterId { get; set; }
        public string InviterName { get; set; }
        public string InviteeEmail { get; set; }
}

private string CreateInviteKey(Invite invite)
{
    var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ConnectionString);

    try
    {
        conn.Open();

        var command = new SqlCommand("GenerateInviteKey", conn);
        command.Parameters.Add(new SqlParameter("@inviterId", SqlDbType.BigInt, 0, "inviter_id"));
        command.Parameters.Add(new SqlParameter("@inviteeEmail", SqlDbType.VarChar, 100, "invitee_email"));
        command.Parameters.Add(new SqlParameter("@inviteKey", SqlDbType.VarChar, 30, "invite_key"));

        command.Parameters[0].Value = invite.InviterId;
        command.Parameters[1].Value = invite.InviteeEmail;
        command.Parameters[2].Direction = ParameterDirection.Output;

        command.ExecuteNonQuery();

        var inviteKey = (string)command.Parameters[2].Value;

        return inviteKey;
   }
   catch (Exception ex)
   {
       var error = ex.Message;
       return null;
   }
   finally
   {
       conn.Close();
       conn.Dispose();
   }
}

存储过程如下所示:

ALTER PROCEDURE [dbo].[GenerateInviteKey] 
    @inviterId int,
    @inviteeEmail varchar(100), 
    @inviteKey varchar(30) OUT
AS
BEGIN
    SET NOCOUNT ON;

    exec dbo.GenerateRandomString 1, 1, 1, null, 30, @inviteKey OUT

    INSERT INTO [dbo].[invite_key] ([invite_key], [inviter_id], [invitee_email], [eff_datetime])
       SELECT 
          @inviteKey, @inviterId, @inviteeEmail, GETDATE()
END

我已经盯着这个东西看了一个小时,试图找出我搞砸的地方,但我需要另一双眼睛。

更新 1:

我已将参数更改为以下模式:

var command = new SqlCommand("GenerateInviteKey", conn);
command.Parameters.Add(new SqlParameter("@inviterId", invite.InviterId));
command.Parameters.Add(new SqlParameter("@inviteeEmail", invite.InviteeEmail));
command.Parameters.Add(new SqlParameter("@inviteKey", ParameterDirection.Output));

并将有问题的过程参数更改为@inviterId bigint,,结果相同。

【问题讨论】:

  • 为什么要使用 SqlParameter 构造函数来获取源列?
  • 习惯的力量,我假设您的评论有更正确的方法来做到这一点。如果是这样,您能提出更好的方法吗?
  • 尝试使用SqlDbType.Integer而不是BigInt,并去掉列名,这样我们就不必考虑它们了。
  • @Rex_C 不知道是不是和你的问题有关,但不是我经常看到的表格。根据 MSDN,它仅用于更新语句,但没有详细说明。一般来说,如果你不知道为什么要传递参数,并且有一个不需要它的重载,我会选择更简单的版本。

标签: c# sql-server


【解决方案1】:

您忘记将 CommandType 设置为 CommandType.StoredProcedure

所以它最终只是传递参数,然后按名称执行过程,并且从不将参数传递给该调用。

【讨论】:

    【解决方案2】:

    在您的过程 def 中,它将 @inviterid 定义为 int,而您的参数 def 试图将其强制转换为 SqlDbType.BigInt。不完全确定,但这可能是问题所在。

    为什么不让您的代码自动确定类型:

        var command = new SqlCommand("GenerateInviteKey", conn);
        command.Parameters.Add(new SqlParameter("@inviterId", invite.InviterId));
        command.Parameters.Add(new SqlParameter("@inviteeEmail", invite.InviteeEmail));
        command.Parameters.Add(new SqlParameter("@inviteKey", ParameterDirection.Output));
    

    【讨论】:

    • 源中是Int64
    • 我之前将 @inviterId 作为 BigInt 得到了相同的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-09
    相关资源
    最近更新 更多