Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php PDO不会对多个查询引发异常_Php_Sql Server_Pdo_Odbc_Pdo Odbc - Fatal编程技术网

Php PDO不会对多个查询引发异常

Php PDO不会对多个查询引发异常,php,sql-server,pdo,odbc,pdo-odbc,Php,Sql Server,Pdo,Odbc,Pdo Odbc,如何让PDO在执行多个查询时引发异常 如果我自己运行错误的sql: $execute($ddl_partial); $execute($insert); 然后我得到了预期的错误: PHP致命错误:未捕获PDO异常:SQLSTATE[42S22]:未找到列:207[Microsoft][ODBC驱动程序13 for SQL Server][SQL Server]无效列名“other”。(SQLExecute[207]at/build/php7.0-41GaEn/php7.0-7.0.8/ext/

如何让PDO在执行多个查询时引发异常

如果我自己运行错误的sql:

$execute($ddl_partial);
$execute($insert);
然后我得到了预期的错误:

PHP致命错误:未捕获PDO异常:SQLSTATE[42S22]:未找到列:207[Microsoft][ODBC驱动程序13 for SQL Server][SQL Server]无效列名“other”。(SQLExecute[207]at/build/php7.0-41GaEn/php7.0-7.0.8/ext/pdo_odbc/odbc_stmt.c:260)

然而,如果我先运行一些好的SQL,然后再运行坏的SQL,那么它就会吞下错误,一切看起来都很好。但是,事后查看数据库可以确认,在错误语句之后,所有查询都会失败

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

$execute($drop);
$execute($ddl_partial);
$execute($insert);
我使用
while($statement->nextRowset())
按原样迭代所有返回的行集,但它只打印了8次:

总而言之:

  • 1-第一滴
  • 1-完整ddl
  • 3-首次插入
  • 1秒下降
  • 1-部分ddl
  • 1-insert的第一条语句(第二条语句错误,所以第三条语句从不执行)
为什么我没有从错误语句中得到错误消息

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

为什么您认为此代码会插入多条记录?@davidstrachan我的查询有3条insert语句。当使用完整的ddl运行它时,它会正确地插入所有3个。当使用partial运行它时,它会出错(应该如此)并回滚事务(没有插入任何记录)。但当同时运行这两个命令时,它会插入3,删除表,插入1,然后结束。然后发布实际代码。@JeffPuckettII有趣的是,以前从未见过这个问题-。我建议将这些值添加到数组中,然后循环执行-这将导致每个插入都有一个单独的执行。简单的事实是,Microsoft SQL PHP驱动程序从来都不是很好,只是因为它们没有太多的用途,所以它们中的错误没有被发现,当它们被发现和报告时,没有人会费心去调查它们,同样是因为它们没有多大用处。我不知道MSSQL是否支持ODBC,但如果支持,也许这是一个更好的选择?
<?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);