Возможно ли в mysql динамически переводить идентификаторы, хранящиеся в строке?

Я импортирую данные комментариев в 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?'

Можно ли написать оператор UPDATE mysql, чтобы найти формат наших упоминаний и заменить только идентификатор новым идентификатором? Конечно, это возможно. Приведите пример (CREATE TABLE для таблицы src, таблицы dst, таблицы сопоставления пользователей + INSERT INTO с некоторыми образцами данных, 2-3-5 строк, + желаемое состояние таблицы dst в формате таблицы). Также укажите точную версию сервера MySQL.

Akina 18.12.2020 20:56

@Акина, это работает?

user43024 18.12.2020 21:19

@Akina MySQL версии 5.6. Я также добавил это к вопросу.

user43024 18.12.2020 21:25

5.6 слишком стар, код будет слишком сложным. Безопасен ли для вас формат хранимой процедуры?

Akina 18.12.2020 21:25

Да, это должно быть хорошо.

user43024 18.12.2020 21:27

Сколько строк маны в таблице id_translations? и вы хотите сделать изменение только один раз вручную?

Bernd Buffen 18.12.2020 21:44
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для...
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
2
6
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
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

Другие вопросы по теме