В MySQL у меня есть триггер:
BEGIN IF (EXISTS(SELECT * FROM devices WHERE device_id = NEW.device_id)) THEN SET NEW.id = NULL; ELSE INSERT INTO objects (object_type) VALUES ('3'); SET NEW.id = LAST_INSERT_ID(); END IF; END
Когда этот триггер получает новый идентификатор (из таблицы объектов), он вставляет идентификатор в столбец id таблицы устройств.
Когда я обращаюсь к нему (например, с mysql_insert_id();
в PHP), его пустой.
Как я могу вернуть id вставки из триггера ( LAST_INSERT_ID();
) в функцию в PHP как mysql_insert_id();
?
Лично я использую хранимые процедуры.
Вот базовый пример с PDO:
Код для создания хранимых процедур :
CREATE DEFINER=`user`@`localhost` PROCEDURE `InsertUser`(IN `Input_username` INT, OUT `Out_ID` INT) LANGUAGE SQL NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT '' BEGIN INSERT INTO users( username) VALUES ( Input_username); SET Out_ID = LAST_INSERT_ID(); SELECT Out_ID; END
И PHP-код :
$insert = "CALL InsertUser(:Input_username, @Out_ID)"; $bdd = new PDO('mysql:host=localhost;dbname=db-name', 'user', 'password'); $stmt = $bdd->prepare($insert); $stmt->bindParam(':Input_username', rand(), PDO::PARAM_STR); // to create random name $stmt->execute(); $tabResultat = $stmt->fetch(); $id_user = $tabResultat['Out_ID']; var_dump($id_user);
Надеюсь, я помог. 🙂
Это по дизайну :
Если хранимая процедура выполняет инструкции, которые изменяют значение
LAST_INSERT_ID()
, измененное значение видно из операторов, которые следуют за вызовом процедуры.Для хранимых функций и триггеров, которые изменяют значение, значение восстанавливается при завершении функции или триггера, поэтому следующие операторы не будут видеть измененное значение.
К сожалению, это создает риск несоответствий между вашей таблицей и objects
, поскольку вставки могут все же произойти за пределами этой процедуры (эту проблему можно было бы перенаправить со строгими ограничениями доступа на таблицу)
Сохраните значение в пользовательской переменной:
CREATE TRIGGER .... BEGIN INSERT INTO objects (object_type) VALUES ('3'); SET NEW.id = LAST_INSERT_ID(); SET @myLastInsertID = LAST_INSERT_ID(); END // INSERT INTO your_table... -- trigger the above SELECT @myLastInsertID; -- here is your value
Просто получите значение от object
😉
INSERT INTO your_table... -- trigger the above SELECT MAX(autoinc_column) FROM objects; -- here is your value!
Временные решения 2 и 3 должны быть завернуты в транзакцию, чтобы гарантировать, что никто не вмешивается в @myLastInsertID
или object
во время процесса.