我有一个框架处理一组简单的(单表(更新查询,这些查询在第二次迭代中始终失败。 在我的框架内,我基于键值(col-data(对的关联数组构建了一个准备好的 UPDATE 查询。
我遇到的问题如下:
foreach ($data as $row) call update($row); // pseudo code
框架为每一行生成(准备好的(更新查询,并返回操作的状态/状态。
第一个查询始终成功执行和更新,但对方法的第二个查询始终返回错误:
键 {键} 的重复条目 {值}
最初,我有一个用于表的组合键,其中 cols B、C、D 是主键。 我尝试删除组合键进行测试,但它在标记为"唯一"(非主要(的 auto-inc 字段上生成错误。
在调试器中跟踪执行,我看到 prepare(( 在哪里成功,但第二个查询在生成上述错误的 execute(( 上失败。
此外,在跟踪过程中,我确保我遇到了以下语句:
$dblink->next_result((;
在生成第二个语句之前。
Mysql 日志显示准备好的语句(对于与第一个语句相同的第二个失败语句(:
UPDATE /* /home/sn-m-beds/classes/MBEDS_mySQL.class.inc:(1982) */ config_cfg SET id_cfg = ?, ent_cfg = ?, hash_cfg = ?, key_cfg = ?, value_cfg = ?, modified_cfg = NOW() WHERE idHash_cfg = ?
$result的内容(来自$result->execute(((是:
affected_rows = -1
insert_id = 0
num_rows = 0
param_count = 6
field_count = 0
errno = 1062
error = "Duplicate entry '31' for key 'id_cfg'"
error_list = {array} (as above)
sqlstate = "23000"
id = 9
因此,很明显,就mysql而言,删除复合主键没有任何影响。
我还尝试在每次迭代中生成(隔离(数据库链接资源,但提供了相同的结果。
不知道我还能看什么...任何建议或想法将不胜感激。
谢谢!
--话筒
更新: 12/23/14:
我对显示绑定/准备的所有代码犹豫不决 - 生成和准备查询涉及大量代码。 我从应用程序的跟踪记录中知道,使用此方法生成的查询总是成功的 - 直到我尝试提交连续查询 - 该框架已经生产了一年多。
我不认为问题出在正在执行的查询中——where 子句判别限定符是针对唯一键 (idHash_cfg( 执行的——在调用这个核心成员函数之前,数据元组被计算,如果 idHash 键存在,则调用一个更新(( 数据库元组的方法,其中 no-idHash 值生成对构建插入命令的方法的调用。 对于两者,$data[] 元组作为参数之一传递给该方法。
一些澄清 - 在框架内,每个类实例化都有一个称为 $data 的受保护成员,它可以是元组数组。 查询生成器为$data关联数组中的每一行构建、准备和执行查询。
第一个查询可执行文件成功 - 所有后续查询都以语法正确(相同的代码(构建,但失败并出现前面描述的错误。
我认为这个问题是mysqli的db-link资源之一;MySQL内部的东西,一个引用或资源,或者你想调用它,正在阻止后续查询的成功执行。
下面是创建 SQL 的表:
*************************** 1. row ***************************
Table: config_cfg
Create Table: CREATE TABLE `config_cfg` (
`id_cfg` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'pkey',
`ent_cfg` char(3) NOT NULL COMMENT 'TLA for entity type',
`hash_cfg` char(32) NOT NULL COMMENT 'hash key for the entity',
`key_cfg` varchar(32) NOT NULL COMMENT 'configuration key value name',
`value_cfg` varchar(32) NOT NULL COMMENT 'value assigned to the key',
`created_cfg` datetime DEFAULT NULL,
`createdBy_cfg` char(32) DEFAULT NULL,
`accessed_cfg` datetime DEFAULT NULL,
`modified_cfg` datetime DEFAULT NULL,
`status_cfg` varchar(50) DEFAULT 'ACTIVE',
`sessionIP_cfg` char(15) DEFAULT NULL,
`idHash_cfg` char(32) DEFAULT NULL,
UNIQUE KEY `id_cfg` (`id_cfg`),
UNIQUE KEY `idHash_cfg` (`idHash_cfg`),
KEY `status_cfg` (`status_cfg`),
KEY `ent_cfg` (`ent_cfg`),
KEY `hash_cfg` (`hash_cfg`),
KEY `key_cfg` (`key_cfg`),
CONSTRAINT `config_cfg_ibfk_1` FOREIGN KEY (`status_cfg`) REFERENCES `status_sts` (`name_sts`)
) ENGINE=InnoDB AUTO_INCREMENT=39 DEFAULT CHARSET=latin1 COMMENT='container for entity configuration settings/values'
1 row in set (0.00 sec)
因此,最初,我有一个复合索引作为主键 - ent,hash和key列的组合。 我删除了该索引 y'day 以消除复合键的复杂性以帮助诊断。 正如您从转储中看到的那样,此时我只是处理常规键。
执行查询的一些代码片段:
if ($result = $dbLink->prepare($this->strQuery)) {
if (call_user_func_array(array($result, 'bind_param'), $bp->refValues($bp->get()))) {
if ($result->execute()) {
// [ snip... ]
} else { // where error reports are coming from
snsError::set(ERROR_FATAL, 'query execution failure');
snsError::set(ERROR_FATAL, $this->strQuery);
snsError::set(ERROR_FATAL, $result->error);
$success = false;
$this->state = DATA_STATUS_MYSQL_ERROR;
}
id_cfg是NOT NULL AUTOINCREMENT
。您根本不应该尝试在 INSERT 语句中设置它。把它排除在外,让 mysql 为你填写!将其从语句和绑定到占位符的值数组中删除。
UPDATE /* /home/sn-m-beds/classes/MBEDS_mySQL.class.inc:(1982) */ config_cfg
SET id_cfg = ?, ent_cfg = ?, hash_cfg = ?, key_cfg = ?, value_cfg = ?, modified_cfg = NOW()
WHERE idHash_cfg = ?