关于cmd.Parameters.Clear() 和存储过程返回参数问题

spiderman_0 2012-06-13 04:54:39
我使用了SqlHelper类 调用带返回参数的存储过程。
但是 但是返回值一直未null,sqlserver测试存储过程正确,
后来发现 cmd.Parameters.Clear() 引起的 注释掉就能得到返回值了
请问大家是怎么处理 存储过程返回值的?
...全文
388 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
spiderman_0 2012-06-14
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]

我 6 楼不是说过过了吗?只有SqlDataReader是实时查询数据,你DataSet是一个离线数据集,一旦数据填充了,就意味着所执行的数据库操作完成了,清空参数自然没事。
[/Quote]
哦 那就是说 DataSet里已经存着那个返回参数了么
qldsrx 2012-06-14
  • 打赏
  • 举报
回复
我 6 楼不是说过过了吗?只有SqlDataReader是实时查询数据,你DataSet是一个离线数据集,一旦数据填充了,就意味着所执行的数据库操作完成了,清空参数自然没事。
spiderman_0 2012-06-14
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

SqlDataReader是实时的读取数据,类似SQLSERVER里面的游标,当你存储过程里面执行了SELECT语句,存储过程运行到那个位置就会立刻返回数据给调用方,但是存储过程本身尚未执行完,要等到SELECT语句执行完也就是SqlDataReader读取到最后一条记录后,存储过程里的SELECT语句才执行完毕,之后运行存储过程中的后续语句,直到存储过程完全运行结束后,才有OUT类型参数的回写……
[/Quote]
嗯清楚了 但是我执行返回DataSet的方法就得到了 代码如下:
public static DataSet ExecuteDataSet(string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
{
DataSet ds = null;
SqlCommand cmd = null;
SqlConnection conn = null;
// we use a try/catch here because if the method throws an exception we want to
// close the connection throw code, because will exist, hence the
// commandBehaviour.CloseConnection will not work
try
{
ds = new DataSet();
conn = new SqlConnection(connectionString);
cmd = new SqlCommand();
PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);
SqlDataAdapter adt = new SqlDataAdapter(cmd);
adt.Fill(ds);
cmd.Parameters.Clear();
return ds;
}
catch (Exception e)
{
throw new ApplicationException(e.Message);
}
finally
{
if (conn != null && conn.State != ConnectionState.Closed)
conn.Close();
}
}
我看到 也清除了参数 但为什么能获取返回参数?
qldsrx 2012-06-14
  • 打赏
  • 举报
回复
SqlDataReader是实时的读取数据,类似SQLSERVER里面的游标,当你存储过程里面执行了SELECT语句,存储过程运行到那个位置就会立刻返回数据给调用方,但是存储过程本身尚未执行完,要等到SELECT语句执行完也就是SqlDataReader读取到最后一条记录后,存储过程里的SELECT语句才执行完毕,之后运行存储过程中的后续语句,直到存储过程完全运行结束后,才有OUT类型参数的回写动作,毕竟这个参数有可能在SELECT语句执行之后发生改变。那么当你关闭SqlDataReader就意味着存储过程肯定是执行结束了的。
spiderman_0 2012-06-14
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

你的原因是你用到了SqlDataReader,你用DataTable缓存结果集就没问题了,因为当你的SqlDataReader没有关闭之前,那个返回型参数将得不到值,但是你在遍历那个SqlDataReader 之前就清空了Parameters,因此返回值无法回写。看看你的Helper中,有没有执行后得到DataTable或者DataSet的方法,有的话直接用那个就绝对不会有问题的。
[/Quote]
我把我的SqlHelper的SqlDataReader贴出来
public static SqlDataReader ExecuteReader(string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
SqlConnection conn = new SqlConnection(connectionString);

// we use a try/catch here because if the method throws an exception we want to
// close the connection throw code, because no datareader will exist, hence the
// commandBehaviour.CloseConnection will not work
try
{
PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
cmd.Parameters.Clear();
return rdr;
}
catch
{
conn.Close();
throw;
}
}
return rdr之前参数被清空了 所以遍历reader后得不到参数,那你说的:当你的SqlDataReader没有关闭之前,那个返回型参数将得不到值怎么理解?
qldsrx 2012-06-14
  • 打赏
  • 举报
回复
开放一个方法,外部传入SqlCommand,有外部对其释放,从你的方法中可以看出,你的SqlCommand只有创建而没有释放过程,这个本身就不对,当然你也无法在SqlDataReader用完之前提前释放SqlCommand,那么这个读取并返回SqlDataReader的操作方法应该由外部提供一个持久性的SqlCommand。
spiderman_0 2012-06-14
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

你的原因是你用到了SqlDataReader,你用DataTable缓存结果集就没问题了,因为当你的SqlDataReader没有关闭之前,那个返回型参数将得不到值,但是你在遍历那个SqlDataReader 之前就清空了Parameters,因此返回值无法回写。看看你的Helper中,有没有执行后得到DataTable或者DataSet的方法,有的话直接用那个就绝对不会有问题的。
[/Quote]
但是我用sqlDataReader主要目的是:
while (dr.Read())
{
ExecProc2012611 Info = new ExecProc2012611();
Info.AddressID = Convert.ToInt32(dr["AddressID"]);
Info.AddressLine1 = dr["AddressLine1"].ToString();
Info.AddressLine2 = dr["AddressLine2"].ToString();
Info.City = dr["City"].ToString();
Info.StateProvinceID = Convert.ToInt32(dr["StateProvinceID"]);
Info.PostalCode = dr["PostalCode"].ToString();
Info.Rowguid = dr["Rowguid"].ToString();
Info.ModifiedDate = Convert.ToDateTime(dr["ModifiedDate"]);
listAccountInfo.Add(Info);
}
给我的实体类赋值,能否注释掉cmd.Parameters.Clear(),有没有办法得到返回值之后再做一次清除。
slovert 2012-06-13
  • 打赏
  • 举报
回复
sqlparameter ss=new sqlparameter("@Rtn");
ss.Direction = ParameterDirection.Output;
执行即可
qldsrx 2012-06-13
  • 打赏
  • 举报
回复
你的原因是你用到了SqlDataReader,你用DataTable缓存结果集就没问题了,因为当你的SqlDataReader没有关闭之前,那个返回型参数将得不到值,但是你在遍历那个SqlDataReader 之前就清空了Parameters,因此返回值无法回写。看看你的Helper中,有没有执行后得到DataTable或者DataSet的方法,有的话直接用那个就绝对不会有问题的。
spiderman_0 2012-06-13
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

因为参数是引用类型,你在代码返回之前都不能清掉,你可以清除掉除了索引是6的其他参数,清除掉后,原来索引为6的参数就变成0了,TotalCount = Convert.ToInt32(parm[0].Value);
[/Quote]
我怎么清除参数时精确到不清除那个返回参数
给你看下SqlHelper中的代码
public static SqlDataReader ExecuteReader(string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
SqlConnection conn = new SqlConnection(connectionString);

// we use a try/catch here because if the method throws an exception we want to
// close the connection throw code, because no datareader will exist, hence the
// commandBehaviour.CloseConnection will not work
try
{
PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
cmd.Parameters.Clear();
return rdr;
}
catch
{
conn.Close();
throw;
}
}
就是那句cmd.Parameters.Clear();
spiderman_0 2012-06-13
  • 打赏
  • 举报
回复
我试一下哦
dopsop110 2012-06-13
  • 打赏
  • 举报
回复
因为参数是引用类型,你在代码返回之前都不能清掉,你可以清除掉除了索引是6的其他参数,清除掉后,原来索引为6的参数就变成0了,TotalCount = Convert.ToInt32(parm[0].Value);
spiderman_0 2012-06-13
  • 打赏
  • 举报
回复
我把代码贴出来 你看看
List<ExecProc2012611> listAccountInfo = new List<ExecProc2012611>();
SqlParameter[] parm =
{
new SqlParameter("@where",SqlDbType.VarChar) ,
new SqlParameter("@tablename",SqlDbType.NVarChar) ,
new SqlParameter("@column",SqlDbType.NVarChar) ,
new SqlParameter("@sort",SqlDbType.NVarChar) ,
new SqlParameter("@pageIndex", SqlDbType.Int),
new SqlParameter("@pageCount",SqlDbType.Int),
new SqlParameter("@TotalCount", SqlDbType.Int)

};
parm[0].Value = where;
parm[1].Value = tablename;
parm[2].Value = column;
parm[3].Value = sort;
parm[4].Value = pageIndex;
parm[5].Value = pageCount;
parm[6].Direction = ParameterDirection.Output;

SqlDataReader dr = SqlHelper.ExecuteReader(SqlHelper.DefaultConnectionString2, CommandType.StoredProcedure, "procPaging2", parm);
while (dr.Read())
{
ExecProc2012611 Info = new ExecProc2012611();
Info.AddressID = Convert.ToInt32(dr["AddressID"]);
Info.AddressLine1 = dr["AddressLine1"].ToString();
Info.AddressLine2 = dr["AddressLine2"].ToString();
Info.City = dr["City"].ToString();
Info.StateProvinceID = Convert.ToInt32(dr["StateProvinceID"]);
Info.PostalCode = dr["PostalCode"].ToString();
Info.Rowguid = dr["Rowguid"].ToString();
Info.ModifiedDate = Convert.ToDateTime(dr["ModifiedDate"]);
listAccountInfo.Add(Info);
}
dr.Close();
TotalCount = Convert.ToInt32(parm[6].Value);
return listAccountInfo;
TotalCount一直是null 原因就是 Sqlhelper中的这句代码cmd.Parameters.Clear();
天下如山 2012-06-13
  • 打赏
  • 举报
回复
应该么有关系吧 我用的也是SqlHelper.cs 但是没遇到过楼主的情况。

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧