php - PDO "Integrity constraint violation - Duplicate entry",但表中没有重复项

标签 php mysql pdo

我在插入查询上收到“重复条目”,该查询与旧的 mysqli 函数配合良好。一旦我转换为 PDO,相同的插入语句就会中断。

这是示例 SQL 数据

CREATE TABLE IF NOT EXISTS `lookup_codes` (
  `id` int(3) NOT NULL,
  `code` varchar(10) NOT NULL,
  PRIMARY KEY (`id`,`code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `lookup_codes` (`id`, `code`) VALUES
(1, 'AR'),
(1, 'CN'),
(1, 'OA'),
(4, 'AR'),
(4, 'OA');

这是示例 php/pdo 代码。 (这不是代码批评请求 - 只是试图将问题归结为一个简单的示例,不要在生产中使用此代码,yada yada)。

    // posted data from user
    $id = 2;
    $arr_codes = array('AR','CN');

    // make sure existing rows do not exist
    try
    {
        $q = "SELECT COUNT(*) FROM lookup_codes WHERE id=:id";
        if ($dbg) { echo "<p>SELECT COUNT(*) FROM lookup_codes WHERE id=$id<br>";}
        $stmt = $dbx_pdo->prepare($q);
        $stmt->bindParam(':id', $id, PDO::PARAM_INT);
        $stmt->execute();
        list($count_rows) = $stmt->fetch(PDO::FETCH_NUM); $stmt->closeCursor();

        if ($count_rows>0)
        {
            try
            {
                $q = "DELETE FROM lookup_codes WHERE id=:id";
                if ($dbg) { echo "<p>DELETE FROM lookup_codes WHERE id=$id<br>";}
                $stmt = $dbx_pdo->prepare($q);
                $stmt->bindParam(':id', $id, PDO::PARAM_INT);
                $stmt->execute();
                $stmt->closeCursor();

            } catch(PDOException $err) {
                echo $err->getMessage());
                exit;
            }

        }

    } catch(PDOException $err) {
        echo $err->getMessage());
        exit;
    }



    // set up prepared statement based on posted data
    foreach ($arr_codes as $code)
    {
        $arr_ip[] = array(
            'id'    => $id,
            'code'  => $code,
        );
    }
    $txt_prepared = join(',', array_fill(0, count($arr_ip), '( ?, ?)'));

    // try inserting
    try 
    {
        $q = "INSERT INTO lookup_codes (id, code) VALUES $txt_prepared";
        $stmt = $dbx_pdo->prepare($q);
        $cb = 1;
        foreach ($arr_ip as $rip)
        {
            $id = $rip['id'];
            $code   = $rip['code'];

            $stmt->bindParam($cb++, $id, PDO::PARAM_INT);
            $stmt->bindParam($cb++, $code, PDO::PARAM_STR);
            if ($dbg) { echo "<b>Binding</b> ($id, $code)<br>";}
        }
        $stmt->execute();
        $stmt->closeCursor();

    } catch(PDOException $err) {
        echo $err->getMessage());
        exit;
    }   

这就是我的测试脚本中的全部内容。没有 header 或元重定向..这里只需运行一次代码。

上面的例子结果是:

Error: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-CN' for key 'PRIMARY'

请注意,它会报告第二个提交的代码的重复内容。

使用mysqli_query()时,相同的INSERT工作得很好。错误日志中没有写入任何错误。

这是怎么回事?

最佳答案

问题在于您绑定(bind)插入查询的方式。您需要将 $stmt->bindParam 更改为 $stmt->bindValue。 bindParam 通过引用获取变量,因此在循环的每次迭代中,当您更改 $id 和 $code 的值时,您正在更改绑定(bind)的值。 bindValue 将从变量中获取值的副本并进行绑定(bind)。

关于php - PDO "Integrity constraint violation - Duplicate entry",但表中没有重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27830189/

相关文章:

php - 不安全的内容。如何在模板中全局更改谷歌字体 url

php - 在 php 中系统化 web 应用程序的错误代码?

php - 有没有办法将 --compressed 传递给 PHP 的 curl_setopt()?

php - 从两个表中选择并在 laravel 中显示所有内容

mysql - Ubuntu 14.04.2 Laravel 4.2.0 PDOException 找不到驱动程序 MySQL

php - 错误消息:Array ( ) 警告:mysqli::query() 期望参数 1 为字符串、对象

php - jQGrid - 从 Grid1 中选择行以填充 Grid2(MySQL、jQuery、PHP)

php - Laravel Eloquent 乘列总和

PHP + MySql,带有多个错误检查的 OR 查询

php - 在 MySQL PDO 中使用 PHP 函数