SqlCommand的重复使用?

57

我不太确定这是否可能。

我目前正在处理一个大学项目,其中一个函数使用了存储过程。我想知道是否可以在同一个函数中采用更新的参数,将相同的SqlCommand实例应用于再次调用存储过程。

假设我在代码中有以下内容:

myConStr = ConfigurationManager.ConnectionStrings["MyConnString"].ConnectionString;
myConn = new SqlConnection(myConStr);
myCommand = new System.Data.SqlClient.SqlCommand("team5UserCurrentBooks3", myConn); 
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.AddWithValue("@book_id", bookID);
myCommand.Parameters.AddWithValue("@user_id", userID);

try
{
    myConn.Open();
    myCommand.ExecuteNonQuery();

是否可以更新MyCommand的参数并再次调用存储过程?

2个回答

63

是的。您需要确保在每次调用之间调用myCommand.Parameters.Clear以清除参数,但没有任何阻止您重用对象。(我不经常使用C#,所以文本中可能会有一两个错误)

myConStr = ConfigurationManager.ConnectionStrings["MyConnString"].ConnectionString;
myConn = new SqlConnection(myConStr);
myConn.Open();

myCommand = new System.Data.SqlClient.SqlCommand("team5UserCurrentBooks3", myConn); 
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.AddWithValue("@book_id", bookID);
myCommand.Parameters.AddWithValue("@user_id", userID);
myCommand.ExecuteNonQuery();

myCommand.Parameters.Clear();
myCommand.CommandText= "NewStoredProcedureName";
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.AddWithValue("@foo_id", fooId);
myCommand.Parameters.AddWithValue("@bar_id", barId);
mycommand.ExecuteNonQuery();

myCommand.Parameters.Clear();
myCommand.CommandText = " SELECT * FROM table1 WHERE ID = @TID;"
myCommand.CommandType = CommandType.Text;
myCommand.Parameters.AddWithValue("@tid", tId);
SqlReader rdr;
rdr = myCommand.ExecuteReader();

5
与保持文本和参数相同的实例重用不同,重用一个实例并在将其变为“新”命令之前清除所有内容的实际应用要少得多(而不是实际创建新命令)。这个答案值得一提的是它可以做到,但除非分析器显示分配是热点,否则请不要在生产代码中这样做,因为这与声明一个通用 int 并在需要整数时无论它在任何给定点意味着什么都使用它一样没有什么意义。 - Jeroen Mostert
1
@JeroenMostert 如果您想使用不同的参数重复执行存储过程,那该怎么办呢?在每次迭代中清除参数是否明智? - Maximilian Burszley
2
@TheIncorrigible1:不会,因为如果您执行的是相同的存储过程,则其参数列表不会更改。在这种情况下,您可以重用命令,但不应清除参数--只需添加它们一次,并在每次迭代中显式设置所有更改的值即可。唯一有意义需要清除参数的情况是,因为有时您希望存储过程应用参数的默认值,而不知道该值是什么--这是可能的,但非常不寻常。 - Jeroen Mostert

18

是的!你绝对可以这样做。在一个函数内,你也可以重复使用同一个连接(我不建议在更大范围内重用连接对象,但是这是可能的)。

你还可以像这样做:

myConStr = ConfigurationManager.ConnectionStrings["MyConnString"].ConnectionString;
using (var cn = new SqlConnection(myConStr) )
using (var cmd = new SqlCommand("team5UserCurrentBooks3", cn) ) 
{
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add("@user_id", SqlDbType.Int).Value = userID;
    cmd.Parameters.Add("@book_id", SqlDbType.Int);
    cn.Open();

    for(int i = 0; i<10; i++)
    {
        cmd.Parameters["@book_id"].Value = i;
        cmd.ExecuteNonQuery();
    }
}

这将运行查询 10 次并每次使用相同的 user_id,但更改 book_idusing 块就像用 try/catch 包装连接一样,以确保它被关闭。


很遗憾,Parameters.Add现在已经过时了。 但我喜欢你使用的想法。 - Dmitris
13
@Dmitris,只有Add(string, object)方法已经过时。其他所有的Add方法都可以正常使用——请参考http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparametercollection.add.aspx获取更多信息。 - LukeH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接