Сбой триггера ПОСЛЕ ОБНОВЛЕНИЯ на MariaDB

#sql #triggers #mariadb

Вопрос:

Я пытаюсь автоматизировать некоторые задачи в базе данных, а не в приложении. У нас есть небольшой MariaDB для продажи билетов. Когда билет продан, его статус должен быть установлен в значение NOT_VALID до тех пор, пока не будет произведена оплата. После оплаты билет необходимо установить на ДЕЙСТВИТЕЛЬНЫЙ. Сам счет — фактура находится в таблице «som_accounting», и с помощью справочной таблицы (som_accountingtickets-из-за ленивых дизайнерских решений) он указывает на билеты. Теперь я пытаюсь автоматизировать, чтобы флаг в таблице билетов был установлен на ДЕЙСТВИТЕЛЬНЫЙ, когда столбец PAYMENTSTATUS в таблице учета меняется с ОТКРЫТОГО (1) на ОПЛАЧЕННЫЙ (3).

Когда я использую это на консоли (dbeaver или терминале), это работает нормально:

 UPDATE som_ticket SET ID_ticketstatus = 4, activation_date = CURRENT_DATE()
WHERE ticketID IN
(SELECT act.ID_ticket FROM som_accountingticket act
   INNER JOIN (SELECT * FROM som_accounting) AS ac
       ON ac.accountingID = act.ID_accounting
   INNER JOIN (SELECT * FROM som_ticket) AS t2
       ON t2.ticketID = act.ID_ticket AND t2.ID_ticketstatus = '1'
   WHERE act.ID_accounting = '565');
 

Теперь я вставил это в триггер и получил ошибку:

 CREATE DEFINER=`<user>`@`%` TRIGGER `somt_au_accounting`
      AFTER UPDATE
      ON `som_accounting`
      
      FOR EACH ROW BEGIN
            
            IF NEW.ID_paymentstatus = 3 AND OLD.ID_paymentstatus = 1 THEN
                UPDATE som_ticket SET ID_ticketstatus = '4', 
                                            activation_date = CURRENT_DATE()
                    WHERE ticketID IN 
                              (SELECT act.ID_ticket FROM som_accountingticket act
                     INNER JOIN (SELECT * FROM som_accounting) AS ac
                                         ON ac.accountingID = act.ID_accounting
                                   INNER JOIN (SELECT * FROM som_ticket) AS t2
                                         ON t2.ticketID = act.ID_ticket
                                   AND t2.ID_ticketstatus = '1'
                                   WHERE act.ID_accounting = OLD.accountingID);
            END IF;
      END
 

База данных сообщает об этом:

 Error synchronizing data with database

Reason:
SQL-Fehler [08]: (conn:3) Could not read resultset: unexpected end of stream, read 0 bytes from 4
Query is: UPDATE d0294220.som_accounting
    SET ID_paymentstatus=?
    WHERE accountingID=?, parameters [3,568]
 

Почему он хорошо работал в консоли, но не в триггере?

MariaDB 10.5.8

Комментарии:

1. Ошибка выглядит так, как будто она вызвана каким-то другим запросом? … Ни одна часть запроса триггера не имеет SET ID_paymentstatus .

2. Набор нового ID_paymanetstatus выполняется в приложении. Если счет оплачивается, пользователь изменяет это значение в приложении с 1 (еще не оплачено) на 3 (оплачено), и триггер прослушивает это изменение и должен сделать все остальное.

3. Тогда единственное, что я вижу, это то, что запрос, перемещенный в триггер, ссылается на ту же таблицу, которая запускает триггер (при внутреннем соединении), что недопустимо. Cannot make changes to a table that is already in use (reading or writing) by the statement invoking the stored function. Эта информация из ограничений триггера MariaDB указана во второй информации о элементе маркера.

4. Теперь я разделил работу. Триггер проверяет только, нужно ли что-то делать: если статус оплаты изменился с 1 на 3, затем вызовите хранимую процедуру и передайте идентификатор учетной записи. Процедура выполняет поиск всех билетов для изменения и устанавливает их ДЕЙСТВИТЕЛЬНЫМИ.