Я импортирую данные комментариев в mysql из одной базы данных в другую, где некоторые данные уже могут существовать. Здесь важно, что в нашей таблице comments есть столбец display_text типа text. Внутри этого столбца у нас есть упоминания о других пользователях, хранящиеся в формате «@{{"user":id}}@», где идентификатор — это число, представляющее идентификатор пользователя в другой таблице. Для одного комментария может быть несколько упоминаний, требующих обновленных идентификаторов.
Поскольку эти пользователи могут уже существовать в новой базе данных, часть нашего процесса импорта заполняет таблицу id_translations столбцами old_id и new_id, сопоставляющими идентификатор пользователя в исходной базе данных с его идентификатором в новой базе данных. Можно ли написать оператор UPDATE mysql, чтобы найти формат наших упоминаний и заменить только идентификатор новым идентификатором?
У меня уже есть метод выбора только тех комментариев, идентификаторы которых нуждаются в обновлении, поэтому операторы можно писать так, как если бы они обновляли всю таблицу.
MySQL версии 5.6. Вот пример того, как выглядят мои таблицы.
CREATE TABLE IF NOT EXISTS `comments` (
`id` int(6) unsigned NOT NULL,
`display_text` text NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS `id_translations` (
`old_id` int(6) unsigned NOT NULL,
`new_id` int(6) unsigned NOT NULL,
PRIMARY KEY (`old_id`, `new_id`)
);
INSERT INTO `comments` (`id`, `display_text`) VALUES
(1, 'Hey @{{"user":12}}@, look at this'),
(2, 'Thats pretty cool'),
(3, '@{{"user":41}}@ could you take a peek at this?');
INSERT INTO `id_translations` (old_id, new_id) VALUES (12, 100), (41, 101);
Цель состоит в том, чтобы комментарии выглядели так:
1, 'Hey @{{"user":100}}@, look at this'
2, 'Thats pretty cool'
3, '@{{"user":101}}@ could you take a peek at this?'
@Акина, это работает?
@Akina MySQL версии 5.6. Я также добавил это к вопросу.
5.6 слишком стар, код будет слишком сложным. Безопасен ли для вас формат хранимой процедуры?
Да, это должно быть хорошо.
Сколько строк маны в таблице id_translations? и вы хотите сделать изменение только один раз вручную?
CREATE PROCEDURE replacing ()
BEGIN
REPEAT
UPDATE comments
SET display_text = CONCAT( LEFT(display_text, LOCATE('@{{"user":', display_text) - 1),
CHAR(0),
( SELECT new_id
FROM id_translations
WHERE old_id = 0 + SUBSTRING(display_text FROM LOCATE('@{{"user":', display_text) + 10)),
CHAR(1),
SUBSTRING(display_text FROM LOCATE('}}@', display_text) + 3))
WHERE LOCATE('@{{"user":', display_text);
UNTIL !ROW_COUNT() END REPEAT;
UPDATE comments
SET display_text = REPLACE(REPLACE(display_text, CHAR(0), '@{{"user":'), CHAR(1), '}}@');
END
DEMO fiddle
Можно ли написать оператор UPDATE mysql, чтобы найти формат наших упоминаний и заменить только идентификатор новым идентификатором? Конечно, это возможно. Приведите пример (CREATE TABLE для таблицы src, таблицы dst, таблицы сопоставления пользователей + INSERT INTO с некоторыми образцами данных, 2-3-5 строк, + желаемое состояние таблицы dst в формате таблицы). Также укажите точную версию сервера MySQL.