使用AddWithValue()的存储过程参数

本文关键字:存储过程 参数 AddWithValue 使用 | 更新日期: 2023-09-27 18:03:25

我正在尝试循环数组[]的元素参数名称和对象[]的对象值使用AddWithValue()。不幸的是,它说"过程或函数'sp_add_Request'期望参数'@RequestType',未提供"。当我运行光标时,我可以看到所有的参数都提供了,我不明白问题在哪里。请帮助。参见下面的代码:

object[] myValues = new Object[] { txtID.Text, ddlAmissionType.Text };
string[] paramsNames = new string[] { "@CHI", "@RequestType"};
dbConn.addData("sp_add_Request", paramsNames, myValues, lbMsg.Text);
父方法:

public static bool addData(string storedProcName, string[] dynamicParamName, object[] aramVals, string msg)
{    
     for (int i = 0; i < dynamicParamName.Length; i++)
     {
          cmd2.Parameters.AddWithValue(dynamicParamName[i], paramVals[i]);
          //cmd2.Parameters.Add(dynamicParamName[i], dynamicParamValues[i]);
          try
          {
             if (cmd2.Connection.State == ConnectionState.Closed)
             {
                 cmd2.Connection.Open();
                 int stat = cmd2.ExecuteNonQuery();    
                 if (stat > 0)
                 {
                     res = true;
                     msg = "Recorded Added successfully";
                     cmd2.Connection.Close();
                     cmd2.Dispose();
                 }
           }
      }    
}

使用AddWithValue()的存储过程参数

在循环中访问数据库,因为该命令是在for循环中执行的。因此,在添加第二个参数之前执行命令。把try块移到for循环之外,应该就没事了。

public static bool addData(string storedProcName, string[] dynamicParamName, object[] paramVals, string msg)
{    
     for (int i = 0; i < dynamicParamName.Length; i++)
     {
          cmd2.Parameters.AddWithValue(dynamicParamName[i], paramVals[i]);
          //cmd2.Parameters.Add(dynamicParamName[i], dynamicParamValues[i]);
     }    
     try
     {
        if (cmd2.Connection.State == ConnectionState.Closed)
        {
            cmd2.Connection.Open();
        }
        int stat = cmd2.ExecuteNonQuery();    
        if (stat > 0)
        {
            res = true;
            msg = "Recorded Added successfully";
            cmd2.Connection.Close();
            cmd2.Dispose();
        }
     }  
}

你可能想把你的连接对象放在using语句中,这样它就会被自动处理。@abatishchev的回答显示了处理ado对象的正确方法。

每次调用方法时创建、使用和处置新的连接/命令对象。这将使用连接池和其他提高性能的技术。

public static bool addData(string storedProcName, string[] dynamicParamName, object[] paramVals, string msg)
{
    SqlParameter[] paramArr = new SqlParameter[dynamicParamName.Length];
    for(int i = 0; i < dynamicParamName.Length; i++)
    {
        paramArr[i] = new SqlParameter(dynamicParamName[i], paramVals[i]);
    }
    using (SqlConnection connection = new SqlConnection(connectionString))
    using (SqlCommand command = connection.CreateCommand())
    {
        command.CommandText = commandText;
        //command.CommandType = CommandType.StoredProcedure ; // if needed
        command.Parameters.AddRange(paramArr);
        connection.Open();
        return command.ExecuteNonQuery() > 0;
    }
}

参见MSDN: SqlParameterCollection.AddRange() method。

也可以使用LINQ:

SqlParameter[] paramArr = dynamicParamName
    .Select((paramName,i) => new SqlParameter(paramName, paramVals[i]).ToArray();

SqlParameter[] paramArr = Enumerable.Range(0, dynamicParamName.Length - 1)
    .Select(i => new SqlParameter(dynamicParamName[i], paramVals[i])
    .ToArray();