Error: Procedure or function expects parameter which was not supplied

Error: Procedure or function expects parameter which was not supplied

目前,我在 Visual Studio 中的程序动态地将我的数据从我的 Repeater 添加到我的数据库中。

现在我需要添加我在 Repeater 之外手动收集的 ID、我的 EventId 和 FormId。

我需要将其添加到:

 sqlCmd.Parameters.Add("@EventId", SqlDbType.Int).Value = eventId;
 sqlCmd.Parameters.Add("@FormId", SqlDbType.Int).Value = formId;

然而,根据我的代码设置方式,当我添加以下代码时会出现错误:

Additional information: Procedure or function 'spInsFormRegistrant' expects parameter '@EventId', which was not supplied.

工作代码(错误代码被注释掉):

 protected void BtnSubmit_Click(object sender, EventArgs e)
 {
            using (SqlConnection sqlConn = new SqlConnection(ConfigurationManager.ConnectionStrings["Events2"].ConnectionString))
            {
                sqlConn.Open();

                using (SqlCommand sqlCmd = new SqlCommand())
                {

                   //sqlCmd.Parameters.Add("@EventId", SqlDbType.Int).Value = eventId;
                   //sqlCmd.Parameters.Add("@FormId", SqlDbType.Int).Value = formId;
                    foreach (RepeaterItem rpItem in RepeaterForm.Items)
                    {
                        Label lblDisplayName = rpItem.FindControl("lblDisplayName") as Label;
                        Label lblColumnName = rpItem.FindControl("lblColumnName") as Label;
                        TextBox txtColumnValue = rpItem.FindControl("txtColumnValue") as TextBox;

                        if (txtColumnValue != null)
                        {
                            sqlCmd.Connection = sqlConn;
                            sqlCmd.CommandType = CommandType.StoredProcedure;
                            sqlCmd.CommandText = "spInsFormRegistrant";
                            sqlCmd.Parameters.Clear();

                            sqlCmd.Parameters.Add("@ColumnName", SqlDbType.NVarChar).Value = lblColumnName.Text;
                            sqlCmd.Parameters.Add("@ColumnValue", SqlDbType.NVarChar).Value = txtColumnValue.Text;

                        sqlCmd.ExecuteNonQuery();
                        }
                    }
                }
            }
            PnlNone.Visible = false;
            PnlExist.Visible = false;
            PnlSuccess.Visible = true;
            PnlFail.Visible = false;
        }

所以我只需要知道在哪里添加 @EventId@FormId 就可以正常运行。每次我尝试它,它都不起作用。为了不产生错误,我必须遗漏一些小东西。或者可能是我的存储过程有问题...?

存储过程

ALTER PROCEDURE [dbo].[spInsFormRegistrant]
    -- Add the parameters for the stored procedure here
     @EventId int,
     @FormId int,
     @ColumnName varchar(100),
    @ColumnValue varchar(100)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
     declare @Query nvarchar(4000)
    declare @ParmDefinition nvarchar(500);

    set @Query = 'INSERT into Registrant(DateCreated,EventId,FormId,'+ (@ColumnName) +') values (CURRENT_TIMESTAMP, @EventId, @FormId, @ColumnValue)'
    set @ParmDefinition = N'@ColumnValue varchar(100)'
    exec sp_executesql @Query, @ParmDefinition, @ColumnValue = @ColumnValue

END

您正在清除参数:

sqlCmd.Parameters.Clear();

您需要一遍又一遍地添加它们:

foreach (RepeaterItem rpItem in RepeaterForm.Items)
{
    Label lblDisplayName = rpItem.FindControl("lblDisplayName") as Label;
    Label lblColumnName = rpItem.FindControl("lblColumnName") as Label;
    TextBox txtColumnValue = rpItem.FindControl("txtColumnValue") as TextBox;

    if (txtColumnValue != null)
    {
        sqlCmd.Connection = sqlConn;
        sqlCmd.CommandType = CommandType.StoredProcedure;
        sqlCmd.CommandText = "spInsFormRegistrant";
        sqlCmd.Parameters.Clear();  //that's fine, keep it

        //just put them in here
        sqlCmd.Parameters.Add("@EventId", SqlDbType.Int).Value = eventId;
        sqlCmd.Parameters.Add("@FormId", SqlDbType.Int).Value = formId;

        sqlCmd.Parameters.Add("@ColumnName", SqlDbType.NVarChar).Value = lblColumnName.Text;
        sqlCmd.Parameters.Add("@ColumnValue", SqlDbType.NVarChar).Value = txtColumnValue.Text;

    sqlCmd.ExecuteNonQuery();
    }
}

您没有为 eventID 和 FormID 添加参数,但您应该尝试使用不同的方法。不要每次都创建参数。您可以在进入 foreach 循环之前只创建一次,然后在循环内仅更改它们的值

// This part never changes so, set it up just one time before the loop
sqlCmd.Connection = sqlConn;
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.CommandText = "spInsFormRegistrant";
sqlCmd.Parameters.Add("@EventId", SqlDbType.Int).Value = eventId;
sqlCmd.Parameters.Add("@FormId", SqlDbType.Int).Value = formId;

// These twos change inside the loop, so we don't need the value here
sqlCmd.Parameters.Add("@ColumnName", SqlDbType.NVarChar);
sqlCmd.Parameters.Add("@ColumnValue", SqlDbType.NVarChar);


foreach (RepeaterItem rpItem in RepeaterForm.Items)
{
    Label lblDisplayName = rpItem.FindControl("lblDisplayName") as Label;
    Label lblColumnName = rpItem.FindControl("lblColumnName") as Label;
    TextBox txtColumnValue = rpItem.FindControl("txtColumnValue") as TextBox;

    if (txtColumnValue != null)
    {
        sqlCmd.Parameters["@ColumnName"].Value = lblColumnName.Text;
        sqlCmd.Parameters["@ColumnValue"].Value = txtColumnValue.Text;
        sqlCmd.ExecuteNonQuery();
    }
}

当然你不需要调用 Parameters.Clear

然后将参数传递给存储过程中的 sp_executesql 调用的方式存在问题。该系统存储过程要求您为查询中使用的每个参数设置数据类型以及这些参数的初始化列表。

你应该写

...
-- Insert statements for procedure here
declare @Query nvarchar(4000)
declare @ParmDefinition nvarchar(500);

set @Query = 'INSERT into Registrant(DateCreated,EventId,FormId,'+ 
             (@ColumnName) +') values (CURRENT_TIMESTAMP, @EventId, @FormId, @ColumnValue)'
set @ParmDefinition = N'@ColumnValue varchar(100), @EventID int, @FormID int'
exec sp_executesql @Query, @ParmDefinition, 
                   @ColumnValue = @ColumnValue,
                   @EventID = @EventID,
                   @FormID = @FormID