Mysql, выберите много строк и назначьте разные значения каждой строке транзакционно

У меня есть простая таблица MySQL 8 вроде этой:

CREATE TABLE IF NOT EXISTS `test_codes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `segment_id` int(11) unsigned NOT NULL,
  `code_id` int(11) DEFAULT 0,
  PRIMARY KEY (`id`)
);

Таблица заполнена случайными значениями

INSERT INTO `test_codes` (`segment_id`) VALUES ('1');
INSERT INTO `test_codes` (`segment_id`) VALUES ('1');
INSERT INTO `test_codes` (`segment_id`) VALUES ('1');
INSERT INTO `test_codes` (`segment_id`) VALUES ('1');
INSERT INTO `test_codes` (`segment_id`) VALUES ('1');
INSERT INTO `test_codes` (`segment_id`) VALUES ('1');
INSERT INTO `test_codes` (`segment_id`) VALUES ('2');
INSERT INTO `test_codes` (`segment_id`) VALUES ('2');
INSERT INTO `test_codes` (`segment_id`) VALUES ('2');
INSERT INTO `test_codes` (`segment_id`) VALUES ('1');
INSERT INTO `test_codes` (`segment_id`) VALUES ('1');

У моих приложений следующая задача: запрос приходит с массивом кодов, например [1,200,10,18], и мне нужно получить 4 строки (равные размеру массива) из базы данных, где code = 0, и обновить code_id на каждой строка со значениями 1,200, 10, 18 переходно.

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

Как я могу это сделать?

После обновления первая выбранная строка будет иметь code_id 1, вторая выбранная строка code_id 200, третья 10 и последняя 18. Другими словами, задача должна найти строки с неназначенными кодами (code_id = 0) и установить значение для каждой строка.

Ссылка: http://sqlfiddle.com/#!9/60e555/1

Так как же таблица может выглядеть потом?

Strawberry 06.04.2021 12:56

Неясно, хотите ли вы обновить code_id до 1,200, 10, 18 или вы хотите обновить первую выбранную строку с code_id до 1, а вторую - с 200 и т. д.

RiggsFolly 06.04.2021 12:57

Пожалуйста, укажите конкретные данные образца (заполните все столбцы) в вопросе и добавьте желаемый результат для этих данных и предоставленных критериев (входной массив).

Akina 06.04.2021 13:00

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

malefstro 06.04.2021 13:01

Я думаю, он хочет обновить строки с кодом = 0 числами, полученными из массива запросов. например, первая строка со значением code = 0 должна быть обновлена ​​на 1, вторая - на 200 и т. д.

kelvin 06.04.2021 13:03

Я предполагаю, что тоже @kelvin, но предположение - мать всего ^% $ £ $%

RiggsFolly 06.04.2021 13:08

На каком языке написано ваше приложение

RiggsFolly 06.04.2021 13:25

Написано в cpp

malefstro 06.04.2021 13:40
Освоение архитектуры микросервисов с 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
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
8
41
2

Ответы 2

MySQL не поддерживает массивы. Я бы посоветовал вам сначала загрузить массив в таблицу. Это просто удобство, но это удобно.

Затем вы можете использовать комплекс update с join, чтобы справиться с этим:

update test_codes tc join
       (select tc2.*,
               row_number() over (order by rand()) as seqnum
        from test_codes tc2
       ) tc2
       on tc2.id = tc.id join
       (select nc.*,
               row_number() over (order by code_id) as seqnum
        from new_codes nc
       ) nc
       on tc2.seqnum = nc.seqnum
    set tc.code_id = nc.code_id;

Обновлено:

Вы можете построить запрос прямо из кодов:

update test_codes tc join
       (select tc2.*,
               row_number() over (order by rand()) as seqnum
        from test_codes tc2
       ) tc2
       on tc2.id = tc.id join
       (select ? as code, 1 as seqnum union all
        select ? as code, 2 union all
        . . .
       ) nc
       on tc2.seqnum = nc.seqnum
    set tc.code_id = nc.code_id;

У меня нет возможности выбрать второй стол.

malefstro 06.04.2021 13:59

@malefstro. . . Вы можете построить стол на лету. Я отредактировал ответ, чтобы показать, как это сделать.

Gordon Linoff 06.04.2021 15:46

Вы можете сделать это с помощью одного оператора, который вы можете встроить в приложение.

update test_codes
join
(
  select id, row_number() over (order by id) rn
  from test_codes
  where code_id = 0
) t on t.id = test_codes.id
join ( 
 -- a table of new values with their positions
 select 1 rn, 1 val union all
 select 2, 200 union all
 select 3, 10 union all
 select 4, 18
) v on v.rn = t.rn
set code_id = v.val

db <> рабочий пример

Какие числа 1,2,3,4?

malefstro 06.04.2021 14:21

@malefstro, эти числа - позиции, на которые вы хотите поместить значения. Т.е. 200 должны занимать позицию 2. Они должны быть созданы приложением.

Serg 06.04.2021 14:24

Хорошо, я понял, это просто числа, начинающиеся с 1 и заканчивающиеся размером массива. они не идентификаторы столбцов

malefstro 06.04.2021 14:32

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