Как в SQL сделать сразу несколько запросов в одном действии

Поддержка
  • @Shogo Я акцентирую потому, что не вижу пока, то что в итоге посылает модуль. Для этого нужно перед запросом добавить кубик включить отладку . В логи после этого будешь видеть что посылает бас. Вероятно вырезается точка с запятой, в таком случае и мускуль так же тебя пошлет. Как нормализует запросы пхп май админ я не в курсе.

  • @Bigma я ж вот скинул )
    И если была бы ошибка в запросе - то действия по отдельности бы не проходили

  • @Shogo Ну тогда только Ghost может ответить

  • Предполагаю, что так и задуманно, так как ответ то надо получить для каждого запроса. А переменная одна.

  • @Bigma думаю что с удалением строки например или обновлением будет тоже самое.
    Плюс там же написано:
    Screenshot_23.png

  • Делай по одному, по хорошему то все равно проверять надо прошел запрос или нет. Вдруг база отвалилась или сеть легла...

  • @Bigma надо сразу(без блокировки базы может вызвать неприемлемые ошибки) ) по одному бы давно уже сделал ))

  • @Shogo там миллисекунды, а в примере который ты даёшь, удаляется вообще любая запись и не факт что та которую выбрал.

  • @Bigma вы опять о том же - пример для того чтобы максимально упросить запрос, напиши я сложный - вариантов дискуссии было бы больше, а пришло бы к тому же - что там доли секунды )

  • Как вариант сделай поле Лок. И сразу за селектом делай запись в лок, а дальше хоть вечность над ней трудись, другие не тронут, потому что Лок.

    Точнее наоборот - сначало лок

  • @Shogo said in Как в SQL сделать сразу несколько запросов в одном действии:

    @Bigma вы опять о том же - пример для того чтобы максимально упросить запрос, напиши я сложный - вариантов дискуссии было бы больше, а пришло бы к тому же - что там доли секунды )

    Если что-то работает не как ожидается, то ищется work around. В случае с select и потом delete он есть. Я не уверен, что нет универсального обходного пути на "ну непременно хочу делать два запроса сразу". Ну не работает оно вот как ты хочешь.
    Вариантов тут два:

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

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

  • @sergerdn Вы прям сильно завернули, банковские операции тут что-ли 😂 ну тогда уже рабочий пример в студию, мне тоже стало интересно.

  • @Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:

    @sergerdn Вы прям сильно завернули, банковские операции тут что-ли 😂 ну тогда уже рабочий пример в студию, мне тоже стало интересно.

    Чего пример? Еще есть функции в базе данных, они могут вернуть данные, а процедуры нет.
    https://stackoverflow.com/questions/3744209/mysql-stored-procedure-vs-function-which-would-i-use-when

  • Я имел ввиду пример скрипта, шаг за шагом, тут 99 % в первые мускуль поставили.

  • @Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:

    Я имел ввиду пример скрипта, шаг за шагом, тут 99 % в первые мускуль поставили.

    Так по ссылке есть конкретный пример шаг за шагом.

    1. создаем функцию, которая выводит "Hello, {some value}!", на вход которой можно подать строку до 20 символов(CHAR(20)).
    2. наполняем таблицу данными
    3. вызываем ее(SELECT hello(name) FROM names;) и получаем ожидаемый результат
    CREATE FUNCTION hello (s CHAR(20))
       RETURNS CHAR(50) DETERMINISTIC
       RETURN CONCAT('Hello, ',s,'!');
    Query OK, 0 rows affected (0.00 sec)
    
    CREATE TABLE names (id int, name varchar(20));
    INSERT INTO names VALUES (1, 'Bob');
    INSERT INTO names VALUES (2, 'John');
    INSERT INTO names VALUES (3, 'Paul');
    
    SELECT hello(name) FROM names;
    +--------------+
    | hello(name)  |
    +--------------+
    | Hello, Bob!  |
    | Hello, John! |
    | Hello, Paul! |
    +--------------+
    3 rows in set (0.00 sec)
    
  • @sergerdn Честно говоря не понял.
    Задача такая. Есть многопоток. Каждый поток пытается ухватить запись, и чтоб другие ее не трогали.
    Мой вариант - сразу лочить не залоченную запись. И дальше с ней работать.
    Ваш вариант проще?

  • @Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:

    @sergerdn Честно говоря не понял.
    Задача такая. Есть многопоток. Каждый поток пытается ухватить запись, и чтоб другие ее не трогали.
    Мой вариант - сразу лочить не залоченную запись. И дальше с ней работать.
    Ваш вариант проще?

    Есть очень простой вариант делать SELECT FOR UPDATE .
    То есть:

    1. в бд есть таблица, у каждой записи поле used, по умолчанию 0
    2. при запросе выбирать данные, где used 0 и СРАЗУ в это же запросе менять used на 1. Это как раз делает SELECT FOR UPDATE .

    Я так делал, там будут нюансы, связанные с множеством блокировок, но если нет стопицот запросов в секунду, они будут незаметны. Так как SELECT FOR UPDATE залочит всю таблицу на INNODB.
    https://dev.mysql.com/doc/refman/8.0/en/select.html

  • @sergerdn Жесть, а зачем всю таблицу то лочить? Я привел пример с полем, когда вообще ничего не лочится. Просто запись выподает из выборки остальных запросов...

  • @Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:

    @sergerdn Жесть, а зачем всю таблицу то лочить? Я привел пример с полем, когда вообще ничего не лочится. Просто запись выподает из выборки остальных запросов...

    Ну оно вот так работает, точнее работало когда то. Сейчас не могу ручаться на 100%. В сфере применения BAS это будет незаметно, так как лок таблицы на наносекунду по время выполнения запроса не повлияет ни на что.
    Таблица лочится ТОЛЬКО на время выполнения одного запроса, чтобы взять запись и поменять у нее поле. Как раз, чтобы другие потоки не схватили ее же. Вариантов тут нет, надо лочить.
    Может сейчас лочится только конкретная запись, не вся таблица. Пойду как я сам доки почитаю.

    Ты дал вариант, при котором другие потоки все таки могут схватить нужную запись.
    Поток 1:

    1. взял запись
    2. изменил у нее флаг

    А между этими пунктами поток 2 успел схватить ее. Это все ненадежно и добавляет свою логику, вместо SELECT FOR UPDATE, который был придуман ради этого.

  • @sergerdn Жесть, один поток повис, а вся таблица залочена. Это прям майсами какое то...