Попытка обновить одну таблицу MySQL данными из двух других таблиц завершается неудачей

#php #mysql #sql

#php #mysql #sql

Вопрос:

Я пытаюсь обновить одну таблицу, в которой хранятся введенные данные от моих сотрудников. В таблице есть три столбца: идентификатор записи, идентификатор поля и значение. Я хочу убедиться, что для каждого поля в таблице this есть строка в соответствии с каждой записью. Таким образом, я написал следующий скрипт php / sql. Мыслительный процесс состоял в том, чтобы получить два массива (один из которых содержит идентификаторы записей, а другой — идентификаторы полей) и проверить таблицу ввода, чтобы увидеть, существует ли существующая строка для каждого поля и записи. Если нет, то используйте инертную команду into, чтобы добавить строку со значением 0, но эта команда не выполняется. Я предполагаю, что это ошибка тайм-аута из-за интенсивности этой функции. Есть предложения?

$db = JFactory::getDBO();

$field_query = 'ВЫБЕРИТЕ идентификатор ИЗ `jos_directory_field`;
$db->setQuery( $field_query );
$fields = $db->loadObjectList();

$ entry_query = 'ВЫБЕРИТЕ идентификатор ИЗ `jos_directory_entry`;
$db->setQuery( $entry_query );
$entries = $db->loadObjectList();

 for($e =0; $e count($entries);$e  ) {
 for($i=0;$i count($fields);$i  ) {
 $insert_query = 'ВСТАВИТЬ В `jos_directory_enf` (entry_id,field_id,field_value)';
 $insert_query .= 'SELECT'.$entries[$e]->id.','.$fields[$ i]->id.',0';
 $insert_query .= 'ИЗ dual, ГДЕ НЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ * ИЗ `jos_directory_enf`;
 $insert_query .= 'ГДЕ entry_id = '.$entries[$e]->id.' и field_id = '.$fields[$ i]->id.')';
 $db->setQuery( $insert_query);
$db-> query();
 }
 }

Комментарии:

1. Это немедленно отключается или, похоже, зависает?

2. И насколько велики таблицы — возможно, вам не хватает памяти из самого PHP просто из-за размера вашей таблицы (ммм, может быть, это маловероятно). Кроме того, на каком COMMIT уровне вы работаете?

3. У вас есть реальная таблица с именем DUAL? Или это перенос из синтаксиса ORACLE?

4. @MarcB Он выполнялся примерно от 30 до 60 секунд, прежде чем выдать внутреннюю ошибку сервера.

5. @X-Zero Мое предположение о проблеме — это тайм-аут через PHP. Я не знаю, каков уровень ФИКСАЦИИ.

Ответ №1:

Очень жаль, что Joomla, похоже, не поддерживает подготовленные инструкции, поскольку они могут повысить производительность при повторных запросах.

Однако в этом случае есть лучший вариант. Вы должны быть в состоянии заменить код PHP одним оператором SQL, используя IGNORE предложение для операторов INSERT . Во-первых, убедитесь, что у вас есть уникальный индекс в столбцах entry_id и field_id jos_directory_enf . Тогда оператор SQL будет выглядеть примерно так:

 INSERT IGNORE INTO `jos_directory_enf` (entry_id,field_id,field_value)
  SELECT e.id, f.id, 0
  FROM jos_directory_entries AS e
    JOIN jos_directory_field AS f
;
  

.

Комментарии:

1. Я предположил, что INSERT IGNORE будет дублировать строки, но я решил запустить его в любом случае с вашим предложением. Он действительно дублирует каждую существующую строку, а также добавляет необходимую.

2. Похоже, вы не создавали уникальный индекс, как я уже упоминал. Если вы это сделаете, дублирующиеся строки вызовут ошибку дублирующего ключа, препятствующую добавлению строк. Это IGNORE предотвратит остановку запроса из-за ошибки.