【问题标题】:c# sql server procedure return object not set to an instance of an objectc# sql server过程返回对象未设置为对象的实例
【发布时间】:2013-06-13 21:49:36
【问题描述】:

我有一个存储过程

create proc GetCodes
@Code varchar(10),
@Page int = 1,
@Rows int = 10,
@output int output

as

select * from(
  Select *, row_number() over(order by code) as RowNum
  from codes
  where code like '%'+@code+'%'
) as tbl
where @Rows = 0 or RowNum between ((@Page - 1) * @Rows + 1) and (@Page * @Rows)
order by code

set @output = @@ROWCOUNT

我有一个 c# 脚本

SqlCommand cmdSelect = new SqlCommand("GetCodes", SQLData);
cmdSelect.CommandType = CommandType.StoredProcedure;
cmdSelect.Parameters.Add(new SqlParameter("@Code", (Request.QueryString["Code"] != null) ? Request.QueryString["Code"] : ""));
cmdSelect.Parameters.Add(new SqlParameter("@Page", (Request.QueryString["Page"] != null) ? Request.QueryString["Page"] : "1"));
cmdSelect.Parameters.Add(new SqlParameter("@Rows", (Request.QueryString["Rows"] != null) ? Request.QueryString["Rows"] : "10"));
cmdSelect.Parameters.Add(new SqlParameter("@output", SqlDbType.Int));
cmdSelect.Parameters["@output"].Direction = ParameterDirection.Output;
SQLData.Open();
SqlDataReader dtrReader = cmdSelect.ExecuteReader();

int numRows = (int)cmdSelect.Parameters["@output"].Value;

它给了我一个错误“对象引用未设置为对象的实例”

int numRows = (int)cmdSelect.Parameters["@output"].Value;

同样的结果,有什么建议吗?

【问题讨论】:

  • 检查您的异常消息或内部异常。您会看到未初始化的内容
  • NullReferenceException 的几乎所有情况都是相同的。请参阅“What is a NullReferenceException in .NET?”获取一些提示。
  • @odyodyodys:内部异常如何显示未初始化的内容?

标签: c# asp.net sql-server stored-procedures


【解决方案1】:

在尝试读取输出参数的值之前,您需要关闭 SqlDataReader。

 SqlDataReader dtrReader = cmdSelect.ExecuteReader();
 ..... do your stuff....
 dtrReader.Close();

 // Without the previous close the Value is still null and casting to int fails
 int numRows = (int)cmdSelect.Parameters["@output"].Value;

来自REMARKS section on SqlDataReader

在使用 SqlDataReader 时,关联的 SqlConnection 是 忙于服务SqlDataReader,不能进行其他操作 在 SqlConnection 上执行而不是关闭它。这是这种情况 直到调用 SqlDataReader 的 Close 方法。例如, 在调用 Close 之前,您无法检索输出参数。

还请记住,使用 SqlConnection、SqlCommand 和 SqlDataReader 等一次性对象的最佳方法是使用 using statement 来关闭和处置对象。所以,例如你可以写

 using(SqlDataReader dtrReader = cmdSelect.ExecuteReader())
 {

     ..... do your stuff....

 } // At the closing brace the dtrReader will b closed and disposed

【讨论】:

  • 你应该使用“使用”。 using (SqlDataReader dtrReader = cmdSelect.ExecuteReader()) { // do stuff } 并且命令也应该关闭。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
相关资源
最近更新 更多