SELECT sql语句的ExecuteNonQuery不返回任何行

时间:2010-11-24 17:15:34

标签: c# sql-server

如何检查ExecuteNonQuery for SELECT sql语句后返回没有行返回没有行?

4 个答案:

答案 0 :(得分:28)

ExecuteNonQuery Method会返回受INSERTUPDATEDELETE影响的行数。此方法用于执行前面所述的DML(数据操作语言)语句。

ExecuteReader Method将返回SELECT的结果集。当您查询一堆结果时,例如来自表,视图等的行,将使用此方法。

ExecuteScalar Method将返回第一行中的单个值,即SELECT语句的第一列。当您希望只返回查询中的一个值时,将使用此方法。

简而言之,使用 ExecuteNonQuery 方法时,SELECT语句没有结果,这是正常的。请改用 ExecuteReader 。使用ExecuteReader方法,将了解通过返回的SqlDataReader对象的实例返回的行数。

int rows = 0;

if (reader.HasRows)
    while (reader.Read())
        rows++;

return rows; // Returns the number of rows read from the reader.

答案 1 :(得分:6)

我认为没有办法做到这一点。将ExecuteScalarselect count(*) where ...一起使用,以计算与原始SELECT查询的条件匹配的行。以下示例,从here转述:

using (SqlCommand thisCommand = 
    new SqlCommand("SELECT COUNT(*) FROM Employee", thisConnection))
{
    Console.WriteLine("Number of Employees is: {0}",
       thisCommand.ExecuteScalar());
}

如果你也需要这些行,我想你已经在使用ExecuteReader

答案 2 :(得分:3)

请改用ExecuteReader方法。这将返回SqlDataReader,其中包含HasRows属性。

ExecuteNonQuery不应用于SELECT语句。

答案 3 :(得分:1)

这已经很晚了,但我最近遇到了这个问题,并认为对于其他人(像我一样)寻求相同问题的帮助会有所帮助。无论如何,我相信你实际上可以按照你想要的方式使用ExecuteNonQuery。但是......您必须将基础SELECT查询调整为存储过程,而不是具有SELECT查询和输出参数,该参数设置为等于行数。

如MSDN文档中所述:

  

虽然ExecuteNonQuery不返回任何行,但是映射到参数的任何输出参数或返回值都会填充数据。

鉴于此,我就是这样做的。顺便说一句,如果有任何缺陷,我会喜欢那里的专家的反馈,但它似乎对我有用。

首先,您的存储过程应该有两个SELECT语句:一个用于返回数据集,另一个用于输出参数以返回记录计数:

CREATE PROCEDURE spMyStoredProcedure
(
     @TotalRows int output
)
AS
BEGIN
     SELECT * FROM MyTable; //see extra note about this line below.
     SELECT @TotalRows COUNT(*) FROM MyTable;
END

其次,添加此代码(在vb.net中,使用SqlCommand等。)。

Dim cn As SqlConnection, cm As SqlCommand, dr As SqlDataReader
Dim myCount As Int32

cn = New SqlConnection("MyConnectionString")
cn.Open() //I open my connection beforehand, but a lot of people open it right before executing the queries. Not sure if it matters.

cm = New SqlCommand("spMyStoredProcedure", cn)
cm.CommandType = CommandType.StoredProcedure
cm.Parameters.Add("@TotalRows", SqlDbType.Int).Direction = ParameterDirection.Output
cm.ExecuteNonQuery()

myCount = CType(cm.Parameters("@TotalRows").Value, Integer)
If myCount > 0 Then
     //Do something.
End If

dr = cm.ExecuteReader()
If dr.HasRows Then
     //Return the actual query results using the stored procedure's 1st SELECT statement
End If
dr.Close()
cn.Close()
dr = Nothing
cm = Nothing
cn = Nothing

就是这样。

额外说明。我假设你可能想要获得“MyCount”金额来做除了确定是否继续返回你的查询以外的事情。原因是因为使用这种方法,你真的不需要这样做。由于我在获取计数后使用“ExecuteReader”方法,因此我可以使用数据读取器的“HasRows”属性确定是否继续返回预期的数据集。但是,要返回数据集,需要一个SELECT语句,它返回一个数据集,因此我的存储过程中第一个SELECT语句的原因。

顺便说一句,关于使用“ExecuteNonQuery”方法的这种方法很酷,你可以使用它在关闭DataReader之前得到总行数(在关闭之前你不能读取输出参数DataReader,这是我试图做的,这个方法可以解决这个问题)。我不确定这个问题是否存在性能损失或缺陷,但就像我说的那样......它对我有用。 = d