|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2008-03-17 14:11 UTC] mfischer@php.net
Description:
------------
I'm using the SQL SELECT result of an PDO query directly in an foreach() loop (via it's iterator capability).
Within this loop I'm doing INSERTs and they violate integrity constraints and thus PDO throws an exception.
I'm catching and basically suppressing the exception. However when the foreach() loop is finished, an exception gets thrown with the line where the foreach() statement is declared.
It seems internally the thrown but silently ignored exception has queued and suddenly being let loose when the foreach() loop finishes.
It doesn't matter whether the SELECT-statement fetches the data from the table where it is inserted or not, this is just done to make the example simpler.
I've also tested with php5.3-win32-200803170030 and it's the same behavior.
It seems to be an similar issue like #39345, but in my case I'm using the mysql driver and the exception is within my PHP source.
Reproduce code:
---------------
<?php
$oPdo = new PDO('mysql:host=db01;dbname=test', 'test', 'test');
$oPdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$oPdo->query('DROP TABLE IF EXISTS test');
$sSqlCreate = <<<SQL
CREATE TABLE `test` (
`a` bigint(20) unsigned NOT NULL,
`b` bigint(20) unsigned NOT NULL,
UNIQUE KEY `unique_ref` (`a`,`b`)
) ENGINE=MyISAM;
SQL;
$oPdo->query($sSqlCreate);
$oPdo->query('TRUNCATE test');
$oPdo->query('INSERT INTO test(a, b) VALUES(1, 1)');
$oResult = $oPdo->query('SELECT * FROM test');
foreach ($oResult as $aRow) {
try {
$oPdo->query('INSERT INTO test(a, b) VALUES(1, 1)');
} catch (Exception $e) { }
}
?>
Expected result:
----------------
Don't throw an exception:
$ php reproduce_pdo_bug.php
# 0
# 1
$
Actual result:
--------------
$ php reproduce_pdo_bug.php
# 0
# 1
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-1' for key 1 in reproduce_pdo_bug.php on line 20
Call Stack:
0.0002 58460 1. {main}() reproduce_pdo_bug.php:0
Patchesfix-mysql_statement.c-5.3-201101041530.patch (last revision 2011-01-04 16:20 UTC by rgagnon24 at gmail dot com)fix-mysql_statement.c-5.2.13.patch (last revision 2010-06-03 18:51 UTC by rgagnon24 at gmail dot com) Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Nov 03 10:00:02 2025 UTC |
No comment on the cause just some observations. Issue exists with SQLite as well. PHP 5.3 CVS MySQL results: emulated prepared statements - not using traversable - OK emulated prepared statement - using traversable - Issue exists native prepared statements - not using traversable - OK native prepared statements - using traversable - OK SQLite: emulated prepared statements - not using traversable - Issue exists emulated prepared statement - using traversable - Issue exists "not using traversable": $stmt = $db->query('SELECT a, b FROM test'); while ($row = $stmt->fetch()) { try { $db->exec('INSERT INTO test(a, b) VALUES (1, 1)'); } catch (Exception $e) { printf("while loop\n"); } } "using traversable": $stmt = $db->query('SELECT a, b FROM test'); foreach ($stmt as $row) { try { $db->exec('INSERT INTO test(a, b) VALUES (1, 1)'); } catch (Exception $e) { printf("foreach\n"); } }Correction: ----------- if ( $conn->errorCode() ) { should be if ( $conn->errorCode() !== '00000' ) {