“El resultado activo no contiene campos” usando PDO con MS SQL

4 minutos de lectura

Avatar de usuario de MrVimes
SrVimes

Estoy en el proceso de convertir algunas páginas antiguas de PHP para usar PDO.

A continuación hay dos consultas simplificadas (no mis consultas reales) para ayudar a comprender el problema que tengo…

SELECT afield INTO #temptable FROM atable WHERE anotherfield = 'somevalue';

SELECT afield,anotherfield,onemorefield FROM atable 
WHERE afield NOT IN (SELECT * FROM #temptable);

La consulta anterior arroja el error descrito en el título (más completamente arroja “Error fatal: excepción no detectada ‘PDOException’ con el mensaje ‘SQLSTATE[IMSSP]: El resultado activo de la consulta no contiene campos.'”)

Si modifico la consulta de esta manera…

with (SELECT afield INTO #temptable FROM atable 
WHERE anotherfield = 'somevalue') AS temptable;

SELECT afield,anotherfield,onemorefield FROM atable 
where afield NOT IN (SELECT * FROM temptable);

Esto parece evitar el error, pero esta versión de la consulta es terriblemente ineficiente porque parece ejecutar la consulta tentable para cada comparación de campo individual en la otra consulta.

¿Hay alguna manera de hacer que el primer formulario (que crea una tabla temporal una vez) funcione con PDO?

Funcionó bien en la página anterior que usaba mssql.

EDITAR: Sé que probablemente pueda hacer esto de una manera ‘desordenada’ al crear una tabla real, ejecutarla en php, luego ejecutar la segunda consulta (en una llamada php separada), luego ejecutar una tercera consulta para eliminar la primera tabla. ¡Pero prefiero no tener que recurrir a eso! 🙂

  • Tenga en cuenta que las palabras clave de SQL como SELECT, WHERE, FROM ... debe estar en mayúsculas. Esto mejorará la legibilidad. Deberías empezar con esto primero.

    – hek2mgl

    24 de mayo de 2013 a las 13:18

  • ¿Está realmente separando las consultas por un punto y coma? ; ?

    – hek2mgl

    24 de mayo de 2013 a las 13:24

  • Intenté eso. No hizo ninguna diferencia.

    – Sr. Vimes

    24 mayo 2013 a las 13:25

  • No tengo SQL Server y no puedo probarlo. Puede ser un problema con la biblioteca sqlclient C subyacente

    – hek2mgl

    24 mayo 2013 a las 13:42


avatar de usuario de user3228005
usuario3228005

Si está utilizando un procedimiento almacenado, utilice

SET NOCOUNT ON 

El problema es que el procedimiento almacenado devuelve un resultado que contiene el número de filas afectadas como primer resultado.

Documentación de Microsoft

  • Desearía haber encontrado esto antes de intentar mi consulta de tantas maneras diferentes. ¡Gracias!

    – dotParx

    11 de septiembre de 2018 a las 10:38


  • DB::select(‘SET NOCOUNT ON; EXEC procedimiento_almacenado’)

    – Raheel Kan

    1 de junio de 2020 a las 8:49

  • En mi caso, no estaba usando un procedimiento almacenado y también funcionó.

    – Doglas

    6 dic 2021 a las 15:00

Avatar de usuario de MrVimes
SrVimes

El motor PDO considera que esta consulta devuelve dos conjuntos de resultados (el motor mssql anterior probablemente ignoró todas las consultas menos la última en una cadena de consulta general). Me las arreglé para que funcione omitiendo el primer conjunto de resultados (la tabla temporal) usando el siguiente comando

$statement->nextRowset();

y luego usando $statement->fetch(); como normal

Si está usando un StoredProcedure y haciendo algo como:

DB::select("EXEC [storedprocedure] $param1,$param2;");

Según lo anterior, el PDO espera el DB::select declaración para devolver algunos datos. pero como tu StoredProcedure no devuelve ningún dato, puedes cambiar DB::select A DB::update como sigue:

DB::update("EXEC [storedprocedure] $param1,$param2;");

Después de esto, el error ya no debería aparecer.

  • Mi SP estaba seleccionando algo solo por error. Al seleccionar algo sobre el éxito también, pude hacer que esto funcionara.

    – DJ Sipe

    4 de abril de 2019 a las 18:25

Me encontré con este problema y las respuestas anteriores ayudaron, pero las respuestas aquí asumen cosas:

  1. Tienes acceso para modificar el sproc con SET NOCOUNT ON y quieres hacer esto
  2. Está seguro de que necesita pasar al siguiente conjunto de filas
    $statement->nextRowset();

En mi caso, estoy usando un método genérico para recuperar datos de múltiples sprocs donde puedo o no tener este problema y necesito verificar antes de incrementar el conjunto de filas.

Usé lo siguiente:

while($stmt->columnCount() === 0 && $stmt->nextRowset()) {
    // Advance rowset until we get to a rowset with data
}

if($stmt->columnCount() > 0) {
    // We found something with data, do stuff.
    // Code here
}

Esperemos que esto ayude a alguien más que se encuentre con un problema similar.

Estoy usando Laravel5 en esta versión, debes ejecutar

DB::select('SET NOCOUNT ON; EXEC stored_procedure'. $param1.','...$paramN);

Funcionó perfecto.

avatar de usuario de marc_s
marc_s

Estoy usando laravel5 y así es como solucioné el problema;

DB::select("SET ANSI_NULLS ON; SET ANSI_WARNINGS ON;EXEC [storedprocedure] $param1,$param2;");

¿Ha sido útil esta solución?