Php PDO不会对多个查询引发异常
如何让PDO在执行多个查询时引发异常 如果我自己运行错误的sql: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/
$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);