在C#中访问SQL Server存储过程输出参数

我有一个简单的SQL Server存储过程:

ALTER PROCEDURE GetRowCount ( @count int=0 OUTPUT ) AS Select * from Emp where age>30; SET @count=@@ROWCOUNT; RETURN 

我试图访问以下C#代码中的输出参数:

 SqlConnection con = new SqlConnection(); con.ConnectionString = "Data Source=localhost\\SQLEXPRESS;Initial Catalog=answers;Integrated Security=True"; SqlCommand cmd = new SqlCommand(); cmd.Connection = con; cmd.CommandText = "GetRowCount"; cmd.CommandType=CommandType.StoredProcedure; cmd.Parameters.Add(new SqlParameter("@count", SqlDbType.Int)); cmd.Parameters["@count"].Direction = ParameterDirection.Output; con.Open(); SqlDataReader reader=cmd.ExecuteReader(); int ans = (int)cmd.Parameters["@count"].Value; Console.WriteLine(ans); 

但是在运行代码时,会在代码的倒数第二行抛出NullReferenceException。 我哪里错了? 提前致谢!

PS我是SQL Procedures的新手,所以我参考了这篇文章 。

我建议你把你的SqlConnectionSqlCommand放到使用块中,以便保证它们的正确处理。

此外,如果我没有弄错,输出参数仅在您完全读取返回的结果数据集后才可用。

既然你根本不需要它 – 为什么不使用.ExecuteNonQuery()呢? 这样可以解决问题吗?

 using (SqlConnection con = new SqlConnection("Data Source=localhost\\SQLEXPRESS;Initial Catalog=answers;Integrated Security=True")) using (SqlCommand cmd = new SqlCommand("dbo.GetRowCount", con)) { cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add(new SqlParameter("@count", SqlDbType.Int)); cmd.Parameters["@count"].Direction = ParameterDirection.Output; con.Open(); cmd.ExecuteNonQuery(); // *** since you don't need the returned data - just call ExecuteNonQuery int ans = (int)cmd.Parameters["@count"].Value; con.Close(); Console.WriteLine(ans); } 

另外:因为看起来你真的只对行数感兴趣 – 为什么不简化你的存储过程到这样的事情:

 ALTER PROCEDURE GetRowCount AS SELECT COUNT(*) FROM Emp WHERE age > 30; 

然后在C#代码中使用此代码段:

  con.Open(); object result = cmd.ExecuteScalar(); if(result != null) { int ans = Convert.ToInt32(result); } con.Close(); 

您必须指定它是存储过程而不是查询

 cmd.CommandType = CommandType.StoredProcedure; 

只需使用ExecuteNonQuery,在这种情况下就不能使用带有out参数的ExecuteReader

 cmd.ExecuteNonQuery(); 

或者,如果您想尝试使用ExecuteScalar和ReturnValue

你应该添加

 cmd.CommandType = CommandType.StoredProcedure 

在打电话之前

我找到了问题,它是连接字符串。 但现在,在代码中:

  usuary = (string)cmd.Parameters["@USUARIO"].Value; password = (string)cmd.Parameters["@CLAVE"].Value; 

编译器infomrs那个值是null …