“完整性约束冲突:1062 重复条目” - 但没有重复行


"Integrity constraint violation: 1062 Duplicate entry" - but no duplicate rows

我正在将应用程序从本机 mysqli 调用转换为 PDO。 尝试将行插入具有外键约束的表中时遇到错误。

注意:这是一个简化的测试用例,不应复制/粘贴到生产环境中。

信息 PHP 5.3, MySQL 5.4

首先,以下是表格:

CREATE TABLE `z_one` (
  `customer_id` int(10) unsigned NOT NULL DEFAULT '0',
  `name_last` varchar(255) DEFAULT NULL,
  `name_first` varchar(255) DEFAULT NULL,
  `dateadded` datetime DEFAULT NULL,
  PRIMARY KEY (`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `z_one` VALUES (1,'Khan','Ghengis','2014-12-17 10:43:01');
CREATE TABLE `z_many` (
  `order_id` varchar(15) NOT NULL DEFAULT '',
  `customer_id` int(10) unsigned DEFAULT NULL,
  `dateadded` datetime DEFAULT NULL,
  PRIMARY KEY (`order_id`),
  KEY `order_index` (`customer_id`,`order_id`),
  CONSTRAINT `z_many_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `z_one` (`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

或者如果你愿意,

mysql> describe z_one;
+-------------+------------------+------+-----+---------+-------+
| Field       | Type             | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+-------+
| customer_id | int(10) unsigned | NO   | PRI | 0       |       |
| name_last   | varchar(255)     | YES  |     | NULL    |       |
| name_first  | varchar(255)     | YES  |     | NULL    |       |
| dateadded   | datetime         | YES  |     | NULL    |       |
+-------------+------------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

mysql> describe z_many;
+-------------+------------------+------+-----+---------+-------+
| Field       | Type             | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+-------+
| order_id    | varchar(15)      | NO   | PRI |         |       |
| customer_id | int(10) unsigned | YES  | MUL | NULL    |       |
| dateadded   | datetime         | YES  |     | NULL    |       |
+-------------+------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

接下来,下面是查询:

    $order_id = '22BD24';
    $customer_id = 1;
    try 
    {
        $q = "
            INSERT INTO 
                z_many 
                (
                    order_id,
                    customer_id,
                    dateadded
                )
            VALUES 
                (
                    :order_id,
                    :customer_id,
                    NOW()
                )
        ";
        $stmt = $dbx_pdo->prepare($q);
        $stmt->bindValue(':order_id', $order_id, PDO::PARAM_STR);
        $stmt->bindValue(':customer_id', $customer_id, PDO::PARAM_INT);
        $stmt->execute();
    } catch(PDOException $err) {
        // test case only.  do not echo sql errors to end users.
        echo $err->getMessage();
    }   

这会导致以下 PDO 错误:

SQLSTATE[23000]:完整性约束冲突:1062 重复条目 "22BD24"表示密钥"主要">

当由 mysqli 处理时,相同的查询工作正常。 为什么PDO在未找到任何重复项时拒绝INSERT并显示"重复条目"消息?

由于并非所有代码都可用(从 php 端(,以防万一您的查询处于某种循环中,因此最快(也许部分(解决方案如下:

$order_id = '22BD24';
$customer_id = 1;
try {
    $q = "INSERT INTO `z_many` (`order_id`,`customer_id`,`dateadded`)
        VALUES (:order_id,:customer_id,NOW())
        ON DUPLICATE KEY UPDATE `dateadded`=NOW()";
    $stmt = $dbx_pdo->prepare($q);
    $stmt->bindValue(':order_id', $order_id, PDO::PARAM_STR);
    $stmt->bindValue(':customer_id', $customer_id, PDO::PARAM_INT);
    $stmt->execute();
} catch(PDOException $err) {
    // test case only.  do not echo sql errors to end users.
    echo $err->getMessage();
}

我已经复制了您在mysql DB上提供的SQL模式并添加了脚本代码,但是在开始时进行了PDO初始化: $dbx_pdo = new PDO('mysql:host=127.0.0.1;dbname=test12;charset=utf8','root','');

.. 它工作正常,但我的设置是 PHP 5.5.9 和 MySQL 5.6.16

所以

我认为你的代码执行两次,也许是在事务内部,所以你会回滚。需要了解更多背景

请删除主键列的默认值。也使用结构

INSERT INTO (`field1`, `field2`, `...`) values (val1, val2, val3);

如果您告诉插入的默认值 - 某些 mysql 版本在插入时可能会看到错误。这就是为什么您应该使用自动增量或根本不使用默认值的原因。

只是在黑暗中射击。我只将 PDO 与 ORACLE PL/SQL 一起使用,并带有 bindParam((。并查看第四个参数,15它是否是PARAM_STR值。所以试试这个,希望它有帮助。

   $stmt->bindParam(':order_id', $order_id, PDO::PARAM_STR, 15);
   $stmt->bindParam(':customer_id', $customer_id, PDO::PARAM_INT);

这 15 表示表中 order_id 的(bufffer-(长度。

相关文章: