PDO löst keine Ausnahme mit mehreren Abfragen aus

Wie kann ich PDO veranlassen, bei der Ausführung mehrerer Abfragen eine Ausnahme auszulösen?

Wenn ich den fehlerhaften SQL-Code selbst ausführe:

$execute($ddl_partial);
$execute($insert);

Dann erhalte ich den erwarteten Fehler:

PHP Schwerwiegender Fehler: PDOException nicht abgefangen: SQLSTATE [42S22]: Spalte nicht gefunden: 207 [Microsoft] [ODBC-Treiber 13 für SQL Server] [SQL Server] Ungültiger Spaltenname 'other'. (SQLExecute [207] unter /build/php7.0-41GaEn/php7.0-7.0.8/ext/pdo_odbc/odbc_stmt.c:260

Wenn ich jedoch zuerst ein gutes SQL-Programm ausführe und anschließend das schlechte SQL-Programm ausführe, wird der Fehler nur verschluckt, und alles scheint in Ordnung zu sein. Wenn Sie sich danach die Datenbank ansehen, stellen Sie sicher, dass alle Abfragen nach der fehlerhaften Anweisung fehlschlagen.

$execute($ddl_full);
$execute($insert);

$execute($drop);
$execute($ddl_partial);
$execute($insert);

Ich durchlaufe alle zurückgegebenen Rowsets mitwhile ($statement->nextRowset()) wie es istdemonstriert in dieser Antwort, aber es wird nur genau 8 Mal gedruckt:

array(4) {
  [0] =>
  string(5) "00000"
  [1] =>
  int(0)
  [2] =>
  string(24) " ((null)[0] at (null):0)"
  [3] =>
  string(0) ""
}

was summiert sich:

1 - erster Tropfen 1 - full ddl 3 - erste Einfügungen 1 - zweiter Tropfen 1 - partielles ddl 1 - erste Anweisung von insert (zweite ist fehlerhaft, dritte wird also nie ausgeführt)

Warum erhalte ich die Fehlermeldung aufgrund der fehlerhaften Anweisung nicht?

<?php

$hostname = 'microsoftsql.example.com';
$database = 'mydb';
$username = 'user';
$password = 'P@55w0rd';
// https://www.microsoft.com/en-us/download/details.aspx?id=50419
$driver   = 'ODBC Driver 13 for SQL Server';

$pdo = new PDO("odbc:Driver=$driver;
    Server=$hostname;
    Database=$database",
    $username,
    $password
);
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$pdo->setAttribute( PDO::ATTR_EMULATE_PREPARES, false  );

$drop = "DROP TABLE testerino;";

$ddl_full = "
    CREATE TABLE testerino (
        value VARCHAR(10),
        other VARCHAR(10)
    );
";

$ddl_partial = "
    CREATE TABLE testerino (
        value VARCHAR(10)
    );
";

$insert = "
    INSERT INTO testerino (value)
    VALUES ('first');

    INSERT INTO testerino (value, other)
    VALUES ('second', 'another');

    INSERT INTO testerino (value)
    VALUES ('third');
";

$execute = function (String $sql) use ($pdo) {
    $pdo->beginTransaction();
    try {
        $statement = $pdo->prepare($sql);
        $statement->execute();
        do {
            /* https://bugs.php.net/bug.php?id=61613 */
            var_dump($statement->errorInfo());
        } while ($statement->nextRowset());
        $pdo->commit();
    } catch (PDOException $e) {
        $pdo->rollBack();
        throw $e;
    } finally {
        $statement->closeCursor();
    }
};

$execute($drop); // not needed first time
$execute($ddl_full);
$execute($insert);

$execute($drop);
$execute($ddl_partial);
$execute($insert);

Dies ist ein großes Problem für mich, da nie eine Ausnahme ausgelöst wird, sodass die Transaktion nicht zurückgesetzt wird und nur 1/3 der Datensätze eingefügt werden. Ich brauche es, um alles oder nichts zu sein.

Ich starte Ubuntu Linux 16.04.1 mit PHP 7.0.8-0ubuntu0.16.04.3 (cli) (NTS) und verbinde mich mit Microsoft SQL Server 2012 (SP3) (KB3072779) - 11.0.6020.0 (X64) mit dem Microsoft® ODBC-Treiber 13 (Vorschau) für SQL Server®

Antworten auf die Frage(0)

Ihre Antwort auf die Frage