插入从触发器生成的ID字段,但不传递

时间:2014-03-07 04:03:45

标签: php mysql

在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(来自objects表)时,它会将id插入到devices表的id列中。

当我引用它时(例如在PHP中使用mysql_insert_id();),它是空的。

如何将触发器(LAST_INSERT_ID();)中的插入ID作为mysql_insert_id();返回到PHP中的函数?

2 个答案:

答案 0 :(得分:3)

我个人使用存储过程。
以下是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);

我希望我有所帮助。 :)

答案 1 :(得分:2)

此行为为by design

  

如果存储过程执行更改LAST_INSERT_ID()值的语句,则更改的值将由过程调用后的语句看到。

     

对于更改值的存储函数和触发器,当函数或触发器结束时,将恢复该值,因此后面的语句将不会看到更改的值。

不幸的是,这会导致您的表与objects之间出现不一致的风险,因为插入操作仍可能在此过程之外发生(此问题可能会在表格中使用复杂的访问限制)

  • 解决方法2:

将值保存在用户变量中:

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
  • 解决方法3:

只需从object;)

获取值即可
INSERT INTO your_table... -- trigger the above
SELECT MAX(autoinc_column) FROM objects; -- here is your value!

应在事务中包含变通办法2和3,以确保在此过程中没有人干扰@myLastInsertIDobject