错误:过程或函数需要未提供的参数

时间:2015-12-26 21:23:08

标签: c# asp.net sql-server stored-procedures repeater

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

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

我需要将其添加到:

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

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

  

附加信息:程序或功能' spInsFormRegistrant'   期望参数' @ EventId',这是未提供的。

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

 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

2 个答案:

答案 0 :(得分:4)

您没有为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调用的方式存在问题。系统storedprocedure要求您为查询中使用的每个参数设置数据类型以及这些参数的初始化列表。

你应该写

...
-- 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

答案 1 :(得分:1)

您正在清除参数:

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();
    }
}