@exotik997

Почему не получаются значения NEW в триггере BEFORE UPDATE?

Написал простой триггер, который перед UPDATE таблицы вносит данные в другие таблицы. Все бы ничего но но значения NEW.id или NEW.object_id пустые если их использовать без DECLARE новой переменной и без внесения данных в эту переменную через SET.
Но даже здесь меня ждал провал, потому что после внесения данных в переменную я получаю данные вида
NAME_CONST('new_id_object',5159)
Если в триггере прописать дебаг то пишет все красиво как и должно быть
<------><------>    22 Query<-->SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT =  NAME_CONST('debug_message',_utf8mb3'Debug: NEW.object_id=14, NEW.id=5024, NEW.date1=2021-02-08, NEW.type=1, NEW.cid=6968' COLLATE 'utf8mb3<------><------>    22 Query<-->commit

триггер:
BEGIN
  DECLARE new_object_id INT;
  SET new_object_id = NEW.object_id;
  GET DIAGNOSTICS new_object_id = NUMBER;
  -- Now you can use new_object_id directly in your trigger logic
  -- For example, you can use it in the INSERT statement
  IF new_object_id != 999 THEN
    INSERT INTO object_param_value_text (object_id, param_id, `value`) VALUES (new_object_id, 1, '123');
    UPDATE object_param_value_text
    SET param_id = 1, `value` = '123' WHERE object_id = new_object_id;
  END IF;
END

Триггер кривоват, тут и INSERT и UPDATE.

Структура таблицы phone_client_item_1
CREATE TABLE `phone_client_item_1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `cid` int(11) NOT NULL DEFAULT 0,
  `object_id` int(11) NOT NULL,
  `type` tinyint(4) NOT NULL DEFAULT 0,
  `source_id` int(11) NOT NULL DEFAULT 0,
  `date1` date DEFAULT NULL,
  `date2` date DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `date1` (`date1`),
  KEY `date2` (`date2`),
  KEY `cid` (`cid`),
  KEY `object_id` (`object_id`),
  KEY `source_id` (`source_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5689 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;


Структура таблицы object_param_value_text
CREATE TABLE `object_param_value_text` (
  `object_id` int(11) NOT NULL DEFAULT 0,
  `param_id` int(11) NOT NULL DEFAULT 0,
  `value` varchar(250) NOT NULL DEFAULT '',
  PRIMARY KEY (`param_id`,`object_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;


Сами SQL запросы на UPDATE и запрос сформированный триггером

<------><------>    42 Prepare<>UPDATE phone_client_item_1 SET cid=?, type=?, source_id=?, date1=?, date2=?,  comment=?, object_id=?, alias=? WHERE id=?
<------><------>    42 Execute<>UPDATE phone_client_item_1 SET cid=6968, type=1, source_id=7, date1=DATE'2021-01-13', date2=NULL,  comment='[LOCAL] ???? ?????', object_id=14, alias='' WHERE id=4990
<------><------>    42 Query<-->INSERT INTO object_param_value_text (object_id, param_id, `value`) VALUES ( NAME_CONST('new_object_id',14), 1, '123')


До этого писал триггер для другой таблицы и там все отрабатывает идеально как и было задуманно.

BEGIN

    -- Get the last inserted ID from the object table
    SELECT `AUTO_INCREMENT` INTO @object_id
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_SCHEMA = 'bgbilling'
    AND TABLE_NAME = 'object';

    -- Modify the values before insert
    SET NEW.date1 = NOW();
    
    -- Use LPAD within CONCAT to format object_id with leading zeros directly
    IF NEW.type_id = 1 THEN
        INSERT INTO object_param_value_text (object_id, param_id, `value`) 
            VALUES (@object_id, 3, CONCAT('sp_', NEW.cid, '-', LPAD(@object_id, 5, '0')));
        INSERT INTO object_param_value_text (object_id, param_id, `value`) 
            VALUES (@object_id, 2, CAST(SUBSTRING(MD5(RAND()), 1, 12) AS CHAR));
        INSERT INTO object_param_value_list (object_id, param_id, `value`) 
            VALUES (@object_id, 10, 16);
        INSERT INTO object_param_value_list (object_id, param_id, `value`) 
            VALUES (@object_id, 11, 20);
        INSERT INTO object_param_value_list (object_id, param_id, `value`) 
            VALUES (@object_id, 12, 21);
        INSERT INTO object_param_value_flag (object_id, param_id, `value`) 
            VALUES (@object_id, 13, 0);
    END IF;
END
  • Вопрос задан
  • 95 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Akina
Сетевой и системный админ, SQL-программист.
Для всех полей, которые не указаны явно в запросе на добавление (то есть поля явно перечислены в предложении INSERT, но это не все поля таблицы, есть неупомянутые в списке поля), в шаблон вставляемой записи помещается указанное в структуре таблицы значение по умолчанию. Если таковое отсутствует, то в шаблон помещается NULL.

Поле-автоинкремент не имеет значения по умолчанию. Генерация нового автоинкрементного значения производится после выполнения всех BEFORE триггеров. Отсюда и NULL в указанной ситуации.

PS. https://xyproblem.info/
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы