mysql — PHP-код для выполнения нескольких подготовленных обновлений запросов завершается с ошибкой с повторяющимся ключом на второй итерации

У меня есть фреймворк, обрабатывающий набор простых (однотабличных) запросов на обновление, которые последовательно терпят неудачу на второй итерации. В рамках моей структуры я создаю подготовленный запрос UPDATE на основе ассоциативного массива пар ключ-значение (col-data).

Проблема, с которой я сталкиваюсь, заключается в следующем:

foreach ($data as $row) call update($row);  // pseudo code

Каркас создает (подготовленный) запрос на обновление для каждой строки и возвращает состояние / статус операции.

Первый запрос всегда выполняется и обновляется успешно, но второй запрос к методу последовательно возвращает ошибку:

Повторяющаяся запись {значение} для ключа {ключ}

Первоначально у меня был составной pkey для таблицы, где столбцы 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.

Я также пытался генерировать (изолировать) ресурсы связи БД на каждой итерации, но те же результаты были получены.

Не уверен, что еще я могу посмотреть … любые предложения или идеи будут высоко оценены.

Спасибо!

—Майк

ОБНОВЛЕНИЕ: 23.12.14:

Я не решаюсь показать весь код для привязки / подготовки — есть много кода, участвующего в создании и подготовке запроса. Это и я знаю из послужного списка приложения, что запросы, сгенерированные с использованием этого метода, всегда были успешными — до тех пор, пока я не попытался отправить последовательные запросы — инфраструктура работает уже более года.

Я не верю, что проблема заключается в том, что выполняемый запрос — квалификатор дискриминанта where-условия выполняется против уникального ключа (idHash_cfg) — до вызова этой основной функции-члена кортеж данных оценивается и, если ключ idHash существует, вызывается метод, который update () является кортежем db, где в качестве значения no-idHash генерируется вызов метода, который создает команду вставки. Для обоих кортеж $ data [] передается методу в качестве одного из аргументов.

Некоторое пояснение — в рамках каждого экземпляра класса есть защищенный член, называемый $ data, который может быть массивом кортежей. Построитель запросов строит, подготавливает и выполняет запрос для каждой строки в ассоциативном массиве $ data.

Первый запрос exec успешно выполнен — ​​все последующие запросы строятся синтаксически правильно (тот же код), но не с ошибкой, описанной ранее.

Я думаю, что эта проблема является одним из ресурсов db-link для mysqli; что-то внутреннее в MySQL, ссылка или ресурс или w / e, который вы хотите вызвать, препятствует успешному выполнению последующих запросов.

Вот таблица создания 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. Я убрал этот индекс сегодня, чтобы устранить сложность сложного ключа, чтобы помочь в диагностике. Как вы можете видеть из дампа, я просто имею дело с обычными ключами на данный момент.

Некоторые фрагменты кода, где выполняется запрос:

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;
}

0

Решение

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 = ?
1

Другие решения

tl; dr: проблема была в коде …

проблемы с индексацией были неуместны … составные ключи, идентификатор и т. д.

вместо того, чтобы анализировать входной кортеж, я выбирал информацию о ключе от члена класса, который по умолчанию (в коде) принимался за 0-й кортеж, если индекс не был передан …. который не был б / к, когда затронутый код был первым -gen и никогда не учитывается для n-кортежей в элементе данных.

как только я реорганизовал основной код для обработки n-кортежей, все работало без сбоев.

спасибо за все комментарии и предложения — это заставило меня начать искать в нужных местах.

-1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector