ExecuteNonQuery para SELECT statement SQL que no devuelve filas

¿Cómo se comprueba si no se devolvieron las filas después de que ExecuteNonQuery for SELECT SQL statement no devuelve filas?

El ExecuteNonQuery Method devuelve la cantidad de filas afectadas por un INSERT , un UPDATE o un DELETE . Este método se debe utilizar para realizar declaraciones DML (lenguaje de manipulación de datos) como se indicó anteriormente.

El ExecuteReader Method devolverá el conjunto de resultados de un SELECT . Este método se debe usar cuando consulta un montón de resultados, como filas de una tabla, vista, lo que sea.

El ExecuteScalar Method devolverá un único valor en la primera fila, primera columna de una instrucción SELECT . Este método se utilizará cuando espere que se devuelva solo un valor de la consulta.

En resumen, es normal que no tenga resultados de una instrucción SELECT mientras usa el método ExecuteNonQuery . Use ExecuteReader en su lugar. Usando el método ExecuteReader , sabrá cuántas filas se devolvieron a través de la instancia del objeto SqlDataReader devuelto.

 int rows = 0; if (reader.HasRows) while (reader.Read()) rows++; return rows; // Returns the number of rows read from the reader. 

No veo ninguna forma de hacer esto. Use ExecuteScalar con select count(*) where … cuente las filas que coinciden con los criterios de su consulta SELECT original. Ejemplo a continuación, parafraseado desde aquí :

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

Si necesita las filas también, ya estaría utilizando ExecuteReader , me imagino.

Use el método ExecuteReader lugar. Esto devuelve un SqlDataReader , que tiene una propiedad HasRows .

ExecuteNonQuery no debe usarse para SELECT .

Esto es tarde, pero me encontré con este problema recientemente y pensé que sería útil que otros llegaran más tarde (como yo) en busca de ayuda con el mismo problema. De todos modos, creo que en realidad podrías usar ExecuteNonQuery de la forma en que lo intentas. PERO … tiene que ajustar su consulta SELECT subyacente a un procedimiento almacenado que tiene una consulta SELECT y un parámetro de salida que se establece para que sea igual al recuento de filas.

Como se indica en la documentación de MSDN:

Aunque ExecuteNonQuery no devuelve ninguna fila, los parámetros de salida o los valores de retorno asignados a los parámetros se rellenan con datos.

Dado que, así es como lo hice. Por cierto, me encantaría recibir retroalimentación por parte de los expertos si hay algún defecto en esto, pero parece funcionar para mí.

Primero, su procedimiento almacenado debe tener dos instrucciones SELECT: una para devolver su conjunto de datos y otra ligada a un parámetro de salida para devolver el conteo de registros:

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

Segundo, agregue este código (en vb.net, usando SqlCommand, etc.).

 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 

Eso es.

Nota extra Supuse que es posible que haya deseado que el monto de “MyCount” haga algo diferente a determinar si continuará volviendo a ser consulta. La razón es porque con este método, realmente no necesitas hacer eso. Dado que estoy utilizando el método “ExecuteReader” después de obtener el conteo, puedo determinar si continuaré devolviendo el conjunto de datos deseado utilizando la propiedad “HasRows” del lector de datos. Sin embargo, para devolver un conjunto de datos, necesita una instrucción SELECT que devuelva un conjunto de datos, de ahí el motivo de mi primera instrucción SELECT en mi procedimiento almacenado.

Por cierto, lo bueno de este método de utilizar el método “ExecuteNonQuery” es que puedes usarlo para obtener el recuento total de filas antes de cerrar el DataReader (no puedes leer los parámetros de salida antes de cerrar el DataReader, que es lo que estaba intentando hacer, este método lo soluciona). No estoy seguro de si hay un golpe de rendimiento o un error al hacer esto para evitar ese problema, pero como dije … me funciona. = D