简体   繁体   中英

Stored Procedure Parameter with AddWithValue()

I am trying to loop thru the elements of an Array[] for Parameter names and Object[] for object values using the AddWithValue() . Unfortunately it is saying "Procedure or function 'sp_add_Request' expects parameter '@RequestType', which was not supplied". When I run to cursor, I can see all the parameters are supplied, I do not understand where the problem is. Please help. See code below:

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

Parent method:

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

You are accessing the database in your loop because the command is executed within the for loop. So you're performing your command before the 2nd parameter is added. Move the try block outside the for loop and you should be fine.

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

You may want to just go ahead and put your connection object in a using statement that way it's automatically disposed. @abatishchev's answer below shows the proper way to handle your ado objects.

Create, use and dispose new connection/command objects each time method is being called. This will use connection pooling and other performance positive techniques.

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

See MSDN : SqlParameterCollection.AddRange() method.

Also you can use LINQ:

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

or

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM