„Das aktive Ergebnis enthält keine Felder“ mit PDO mit MS SQL

Lesezeit: 4 Minuten

Benutzeravatar von MrVimes
MrVimes

Ich bin dabei, einige alte PHP-Seiten zu konvertieren, um PDO zu verwenden.

Unten sind zwei vereinfachte Abfragen (nicht meine eigentlichen Abfragen), um das Verständnis meines Problems zu erleichtern …

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

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

Die obige Abfrage wirft den im Titel beschriebenen Fehler (vollständiger wirft sie „Fatal error: Uncaught exception ‘PDOException’ with message ‘SQLSTATE[IMSSP]: Das aktive Ergebnis der Abfrage enthält keine Felder.'”)

Wenn ich die Abfrage so verändere…

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);

Dies scheint den Fehler zu umgehen, aber diese Version der Abfrage ist schrecklich ineffizient, da sie die verlockbare Abfrage für jeden einzelnen Feldvergleich in der anderen Abfrage auszuführen scheint.

Gibt es eine Möglichkeit, das erste Formular (das einmalig eine temporäre Tabelle erstellt) mit PDO zum Laufen zu bringen?

Auf der alten Seite, die mssql verwendete, funktionierte es gut.

BEARBEITEN: Ich weiß, dass ich dies wahrscheinlich auf “unordentliche” Weise tun kann, indem ich eine echte Tabelle erstelle, sie in PHP ausführe, dann die zweite Abfrage (in einem separaten PHP-Aufruf) ausführe und dann eine dritte Abfrage ausführe, um die erste Tabelle zu löschen. Darauf muss ich aber lieber nicht zurückgreifen! 🙂

  • Beachten Sie, dass SQL-Schlüsselwörter wie SELECT, WHERE, FROM ... sollte großgeschrieben werden. Dadurch wird die Lesbarkeit verbessert. Damit solltest du erstmal anfangen

    – hek2mgl

    24. Mai 2013 um 13:18 Uhr

  • Trennen Sie die Abfragen tatsächlich durch ein Semikolon? ; ?

    – hek2mgl

    24. Mai 2013 um 13:24 Uhr

  • Habe das versucht. Machte keinen Unterschied.

    – MrVimes

    24. Mai 2013 um 13:25 Uhr

  • Ich habe keinen SQL Server und kann ihn nicht testen. Es kann ein Problem mit der zugrunde liegenden sqlclient-C-Bibliothek sein

    – hek2mgl

    24. Mai 2013 um 13:42 Uhr


Benutzeravatar von user3228005
Benutzer3228005

Wenn Sie eine gespeicherte Prozedur verwenden, verwenden Sie

SET NOCOUNT ON 

Das Problem besteht darin, dass die gespeicherte Prozedur als erstes Ergebnis ein Ergebnis zurückgibt, das die Anzahl der betroffenen Zeilen enthält.

Microsoft-Dokumentation

  • Ich wünschte, ich hätte das gefunden, bevor ich meine Abfrage auf so viele verschiedene Arten versucht habe. Danke schön!

    – dotParx

    11. September 2018 um 10:38 Uhr


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

    – Rahel Khan

    1. Juni 2020 um 8:49 Uhr

  • In meinem Fall habe ich keine gespeicherte Prozedur verwendet und es hat auch funktioniert.

    – Doglas

    6. Dezember 2021 um 15:00 Uhr

Benutzeravatar von MrVimes
MrVimes

Die PDO-Engine sieht diese Abfrage als Rückgabe von zwei Resultsets (die ältere mssql-Engine hat wahrscheinlich nur alle außer der letzten Abfrage in einer Gesamtabfragezeichenfolge ignoriert). Ich habe es geschafft, dass es funktioniert, indem ich die erste Ergebnismenge (die temporäre Tabelle) mit dem folgenden Befehl übersprungen habe

$statement->nextRowset();

Und dann verwenden $statement->fetch(); wie normal

Wenn Sie eine verwenden StoredProcedure und etwas tun als:

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

Wie oben, die PDO erwartet die DB::select Anweisung, um einige Daten zurückzugeben. Aber als dein StoredProcedure gibt keine Daten zurück, Sie können ändern DB::select ZU DB::update wie folgt:

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

Danach sollte der Fehler nicht mehr auftreten.

  • Mein SP hat nur im Fehlerfall etwas ausgewählt. Indem ich auch etwas bei Erfolg auswählte, konnte ich dies zum Laufen bringen.

    – DJ Sipe

    4. April 2019 um 18:25 Uhr

Ich bin auf dieses Problem gestoßen und die obigen Antworten haben geholfen, aber die Antworten hier setzen Dinge voraus:

  1. Sie haben Zugriff, um den Sproc mit zu modifizieren SET NOCOUNT ON und Sie möchten dies tun
  2. Sie sind sicher, dass Sie zum nächsten Rowset wechseln müssen
    $statement->nextRowset();

In meinem Fall verwende ich eine generische Methode, um Daten aus mehreren Sprocs zurückzuziehen, bei denen ich dieses Problem möglicherweise habe oder nicht, und dies überprüfen musste, bevor das Rowset erhöht wurde.

Ich habe folgendes verwendet:

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
}

Hoffentlich hilft dies jemand anderem, der auf ein ähnliches Problem stößt.

Ich verwende Laravel5 in dieser Version, die Sie ausführen sollten

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

Es funktionierte perfekt.

Benutzeravatar von marc_s
marc_s

Ich verwende Laravel5 und so habe ich das Problem behoben;

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

1444770cookie-check„Das aktive Ergebnis enthält keine Felder“ mit PDO mit MS SQL

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy