下面的第二条SQL语句在phpMyAdmin中返回错误:
SET @num=2000040;
INSERT INTO artikel( artikel_nr, lieferant_nr, bezeichnung_1, bezeichnung_1 )
SELECT @num := @num +1 AS anum, 70338, f2, f3
FROM import
WHERE id >1
MySQL说:
#1110 - Column 'bezeichnung_1' specified twice
一切正确。但是,当我使用此函数在Symfony 1.4中运行查询时:
// run sql query
// http://erisds.co.uk/symfony/snippet-creating-debugging-complex-sql-queries-in-symfony
// http://stackoverflow.com/questions/5434702/php-quick-refactoring
// param $sql: the query to run
// param $silent: bool if errors should be ignored
// throws: pdo error info if statement failed and $silent=false
// returns: pdo-statement (use for looping over result rows and error messages)
public static function runQuery($sql, $silent=false)
{
$conn = Propel::getConnection();
$pdo_statement = $conn->prepare($sql);
$error = null;
try
{
$pdo_statement->execute();
}
catch (Exception $e)
{
$error = $e->getMessage();
}
if ( !$error )
{
$pdo_error = $pdo_statement->errorInfo();
$error = $pdo_error[2];
}
if ( !$silent && $error ) throw new Exception($error);
return $pdo_statement;
}
不会抛出任何错误。这两个SQL语句必须同时提交,因为它们相互依赖。错误查询是根据用户输入构造的。我需要重新获得该错误,否则我无法判断数据库是否已更改,我无法告诉用户它。
你知道为什么PDO不抱怨无效声明,如果不能这样做,如何获得成功/失败信息?
BTW如果没有重复的列,查询会更新数据库。
以下是PDOStatement类的链接:http://www.php.net/manual/en/class.pdostatement.php
答案 0 :(得分:8)
这是预期的行为。由于有两个语句且第一个语句有效,因此必须使用nextRowset()
try
{
$pdo_statement->execute();
while ($pdo_statement->nextRowset()) {/* https://bugs.php.net/bug.php?id=61613 */};
}
答案 1 :(得分:4)
默认情况下PDOStatement::execute()
不会抛出任何异常,只会在出错时返回false。您必须将错误处理设置为PDO::ERRMODE_EXCEPTION
到db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
。
答案 2 :(得分:0)
如果您可以选择使用mysqli
代替PDO进行多次查询,则可以使用mysqli_multi_query
。由于错误处理有点复杂,这是我的功能:
/**
* Executes multiple queries at once (separated by semicolons) and discards the results
*
* @param string $sql
* @throws RuntimeException if a query failed
*/
function multi_query($sql) {
$mysqli = new mysqli('host', 'user', 'password', 'database');
//Execute all queries
$index = 1;
if ($mysqli->multi_query($sql)) {
do {
// next_result() fails if store_result() is not called
if ($result = $mysqli->store_result()) {
$result->free();
}
$has_next = $mysqli->more_results();
if (!$has_next)
return; // all queries successfully executed
$index++;
} while ($mysqli->next_result());
}
// At this point, either the multi_query() has returned false - which is
// when the first query failed - or more_results() was true, while next_result()
// returned false - which is when a different query failed.
$error = $mysqli->error;
if (!$error)
$error = $mysqli->errno ? "errno $mysqli->errno" : '(unknown error)';
throw new RuntimeException("mysqli query $index failed: $error");
}