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

目前,我在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添加的@EventId ,以便正常运行。 每次我尝试它,它都不起作用。 我必须遗漏一些小的东西,以免产生错误。 或者也许这是我的存储过程的问题……?

存储过程

 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 

您没有为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 

您正在清除参数:

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