简体   繁体   English

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

[英]ExecuteNonQuery for SELECT sql statement returning no rows

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

The ExecuteNonQuery Method returns the number of row(s) affected by either an INSERT , an UPDATE or a DELETE . ExecuteNonQuery Method返回受INSERTUPDATEDELETE影响的行数。 This method is to be used to perform DML (data manipulation language) statements as stated previously. 如前所述,该方法用于执行DML(数据操作语言)语句。

The ExecuteReader Method will return the result set of a SELECT . ExecuteReader Method将返回SELECT的结果集。 This method is to be used when you're querying for a bunch of results, such as rows from a table, view, whatever. 当您查询一堆结果时,例如来自表,视图等的行,将使用此方法。

The ExecuteScalar Method will return a single value in the first row, first column from a SELECT statement. ExecuteScalar Method将在SELECT语句的第一行,第一列中返回单个值。 This method is to be used when you expect only one value from the query to be returned. 当您希望仅返回查询中的一个值时,将使用此方法。

In short, that is normal that you have no results from a SELECT statement while using the ExecuteNonQuery method. 简而言之,使用ExecuteNonQuery方法时, SELECT语句没有结果是正常的。 Use ExecuteReader instead. 请改用ExecuteReader Using the ExecuteReader method, will will get to know how many rows were returned through the instance of the SqlDataReader object returned. 使用ExecuteReader方法,将了解通过返回的SqlDataReader对象的实例返回的行数。

int rows = 0;

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

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

I don't see any way to do this. 我认为没有办法做到这一点。 Use ExecuteScalar with select count(*) where ... to count the rows that match the criteria for your original SELECT query. 使用ExecuteScalarselect count(*) where ...来计算与原始SELECT查询的条件匹配的行。 Example below, paraphrased from here : 以下示例,从这里解释:

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

If you need the rows as well, you would already be using ExecuteReader , I imagine. 如果你也需要这些行,我想你已经在使用ExecuteReader

Use the ExecuteReader method instead. 请改用ExecuteReader方法。 This returns a SqlDataReader , which has a HasRows property. 这将返回一个SqlDataReader ,它具有HasRows属性。

ExecuteNonQuery shouldn't be used for SELECT statements. ExecuteNonQuery不应该用于SELECT语句。

This is late, but I ran into this problem recently and thought it would be helpful for others coming in later (like me) seeking help with the same problem. 这已经很晚了,但我最近遇到了这个问题,并认为对于其他人(像我一样)寻求相同问题的帮助会有所帮助。 Anyway, I believe you actually could use the ExecuteNonQuery they way you are trying to. 无论如何,我相信你实际上可以按照你想要的方式使用ExecuteNonQuery。 BUT... you have to adjust your underlying SELECT query to a stored procedure instead that has SELECT query and an output parameter which is set to equal the row count. 但是......您必须将基础SELECT查询调整为存储过程,而不是具有SELECT查询和输出参数,该参数设置为等于行数。

As stated in the MSDN documentation: 如MSDN文档中所述:

Although the ExecuteNonQuery returns no rows, any output parameters or return values mapped to parameters are populated with data. 虽然ExecuteNonQuery不返回任何行,但是映射到参数的任何输出参数或返回值都会填充数据。

Given that, here's how I did it. 鉴于此,我就是这样做的。 By the way, I would love feedback from the experts out there if there are any flaws in this, but it seems to work for me. 顺便说一句,如果有任何缺陷,我会很高兴那里的专家反馈,但它似乎对我有用。

First, your stored procedure should have two SELECT statements: one to return your dataset and another tied to an output parameter to return the record count: 首先,您的存储过程应该有两个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

Second, add this code (in vb.net, using SqlCommand etc..). 其次,添加此代码(在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

That's it. 而已。

Extra note. 额外的说明。 I assumed you may have wanted to get the "MyCount" amount to do something other than determining whether to continue returning you're query. 我假设你可能想要获得“MyCount”金额来做除了确定是否继续返回你的查询以外的事情。 The reason is because with this method, you don't really need to do that. 原因是因为使用这种方法,你真的不需要这样做。 Since I'm utilizing the "ExecuteReader" method after getting the count, I can determine whether to continue returning intended data set using the data reader's "HasRows" property. 由于我在获取计数后使用“ExecuteReader”方法,因此我可以使用数据读取器的“HasRows”属性确定是否继续返回预期的数据集。 To return a data set, however, you need a SELECT statement which returns a data set, hence the reason for my 1st SELECT statement in my stored procedure. 但是,要返回数据集,需要一个返回数据集的SELECT语句,因此我的存储过程中第一个SELECT语句的原因。

By the way, the cool thing about this method of using the "ExecuteNonQuery" method is you can use it to get the total row count before closing the DataReader (you cannot read output parameters before closing the DataReader, which is what I was trying to do, this method gets around that). 顺便说一句,关于使用“ExecuteNonQuery”方法的这种方法很酷的是你可以关闭DataReader 之前使用它来获取总行数( 关闭DataReader 之前你无法读取输出参数,这就是我想要的做,这个方法绕过那个)。 I'm not sure if there is a performance hit or a flaw in doing this to get around that issue, but like I said... it works for me. 我不确定这个问题是否存在性能损失或缺陷,但就像我说的那样......它对我有用。 =D = d

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM