Есть ли способ игнорировать столбцы, которые не существуют на INSERT? - PullRequest
20 голосов
/ 09 октября 2011

Я использую MySQL GUI для переноса некоторых сайтов в новую версию CMS, выбрав определенные таблицы и выполнив инструкцию INSERT, сгенерированную из резервной копии, в пустую таблицу (новуюсхемы).В старых таблицах есть несколько столбцов, которых нет в новой, поэтому сценарий останавливается с ошибкой, подобной этой:

Строка сценария: 1 Неизвестный столбец 'user_id' в поле 'list '

Выбор нужных столбцов для экспорта или редактирование файла дампа будет слишком утомительным и отнимает много времени.Чтобы обойти это, я создаю неиспользуемые столбцы по мере возникновения ошибок, импортирую данные, выполняя запрос, а затем отбрасываю неиспользуемые столбцы, когда я закончу с этой таблицей.Я посмотрел на INSERT IGNORE, но это похоже на игнорирование дублирующихся ключей (не то, что я ищу).

Есть ли способ предварительно отформатировать INSERT, игнорируя столбцы, которые не 'не существует в целевой таблице?Я ищу что-то "безболезненное", как некоторые существующие функции SQL.

Чтобы уточнить, я работаю с кучей файлов резервных копий и импортирую данные в локальную базу данных для тестирования, прежде чем переносить их на работающий сервер.Пример того решения, на которое я надеюсь:

-- Don't try to insert data from columns that don't exist in "new_table"
INSERT INTO `new_table` {IGNORE UNKNOWN COLUMNS} (`id`, `col1`, `col2`) VALUES 
  (1, '', ''),
  (2, '', '');

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

Ответы [ 6 ]

5 голосов
/ 30 октября 2011

Ваша текущая техника кажется достаточно практичной.Только одно небольшое изменение.

Вместо того, чтобы ждать ошибки и затем создавать столбцы один за другим, вы можете просто экспортировать схему, сделать разность и найти все недостающие столбцы во всех таблицах.

Таким образом, будет меньше работы.

Ваш графический интерфейс сможет экспортировать только схему, или следующий ключ на mysqldump будет полезен для поиска всех отсутствующих столбцов.

mysqldump --no-data -uuser -ppassword --database dbname1 > dbdump1.sql
mysqldump --no-data -uuser -ppassword --database dbname2 > dbdump2.sql

Различие dbdump1.sql и dbdump2.sql даст вам все различия в обеих базах данных.

3 голосов
/ 09 октября 2011

Вы можете написать функцию магазина следующим образом:

sf_getcolumns(table_name varchar(100))

возвращает строку, содержащую список полей: 'Field_1, field_2, field_3, ...

затем создайте процедуру хранения

sp_migrite (IN src_db varchar(50), IN target_db varchar(50))

, который запускает таблицы и для каждой таблицы получает списки полей, а затем создает строку типа

cmd = 'insert into ' || <target_db><table_name> '(' || <fileds_list> || ') SELECT' || <fileds_list> || ' FROM ' <src_db><table_name>

затем выполнить строку для каждой таблицы

1 голос
/ 27 октября 2011

Есть ли способ предварительно вставить INSERT, игнорируя столбцы, которых нет в целевой таблице? Я ищу что-то "безболезненное", например, некоторые существующие функции SQL.

Нет, для этого нет "безболезненного" способа.

Вместо этого вы должны явно обрабатывать те столбцы, которых нет в финальных таблицах. Например, вы должны удалить их из входного потока, удалить их после свершившегося факта, сыграть грязные трюки (engine=BLACKHOLE + вызывает INSERT только то, что вы хотите к истинной целевой схеме), что угодно. *

Теперь это не обязательно должно быть manual - есть инструменты (как заметил Devart ) и способы запроса каталога БД для определения имен столбцов. Однако это не так просто, как просто комментировать ваши операторы INSERT.

Возможно, поставщик CMS может предоставить разумный сценарий миграции?

0 голосов
/ 23 февраля 2014

Я внимательно прочитал все эти посты, потому что у меня такой же вызов.Пожалуйста, просмотрите мое решение:

Я сделал это на C #, но вы можете сделать это на любом языке.

Проверьте оператор вставки для имен столбцов.Если что-то отсутствует в вашей фактической таблице, ДОБАВЬТЕ их как столбец ТЕКСТ, потому что ТЕКСТ может съесть что-нибудь.

После завершения вставки в эту таблицу удалите добавленные столбцы.

Готово.

0 голосов
/ 26 октября 2011

нашел ваш вопрос интересным.

Я знал, что есть способ выбрать имена столбцов из таблицы в MySQL;это show columns from tablename.Что я забыл, так это то, что все данные таблиц MySQL хранятся в специальной базе данных, которая называется «information_schema».

Это логическое решение, но оно не работает:

mysql> insert into NEW_TABLE (select column_name from information_schema.columns where table_name='NEW_TABLE') values ...

Я буду продолжать искать, хотя.Если из запроса select column_name можно получить значение, разделенное запятыми, возможно, вы заняты.

Редактировать:

Команду select ... from ... into можно использовать для генерациистрока CSV, например:

mysql> select column_name from information_schema.columns where table_name='NEW_TABLE' into outfile 'my_file' fields terminated by '' lines terminated by ', '

Я не знаю, как получить это для вывода в стандартный вывод MySQL CLI.

0 голосов
/ 25 октября 2011

dbForge Studio for MySQL даст вам возможность сравнивать и синхронизировать данные между двумя базами данных.

По умолчанию сравнение данных выполняется только для объектов содни и те же имена;Вы можете использовать автоматическое сопоставление или сопоставление объектов базы данных вручную.dbForge Studio позволяет вам настраивать отображение таблиц и столбцов, чтобы вы могли сравнивать данные объектов с неравными именами, владельцами и структурой.Вы также можете отобразить столбцы с различными типами, однако это может привести к усечению данных, округлению и ошибкам при синхронизации для определенных типов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...