在插入触发器之前使用MYSQL中的自动增量值?

时间:2014-06-25 09:09:48

标签: mysql triggers

用户表:

CREATE TABLE `users` (
  `id` int(8) unsigned NOT NULL AUTO_INCREMENT,
  `email` varchar(45) DEFAULT NULL,
  `username` varchar(16) DEFAULT NULL,
  `salt` varchar(16) DEFAULT NULL,
  `password` varchar(128) DEFAULT NULL,
  `lastlogin` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `joined` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `loggedin` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `sessionkey` varchar(60) DEFAULT NULL,
  `verifycode` varchar(16) DEFAULT NULL,
  `verified` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `banned` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `locked` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `ip_address` varchar(45) DEFAULT NULL,
  `failedattempts` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `unlocktime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;

user_records表:

CREATE TABLE `user_records` (
  `id` int(8) unsigned NOT NULL AUTO_INCREMENT,
  `userid` int(8) unsigned DEFAULT NULL,
  `action` varchar(100) DEFAULT NULL,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;

users表上的before insert触发器:

USE `gknet`;
DELIMITER $$
CREATE DEFINER=`root`@`localhost` TRIGGER `before_create_user` BEFORE INSERT ON `users` FOR EACH ROW BEGIN
INSERT INTO user_records (action, userid, timestamp)
  VALUES ('CREATED', ID, NOW() );
END

基本上,我的问题是当我尝试输入由MySQL自动分配的用户的id(PK,NN,自动增量)时触发器,它只是为user_records表中的userid输入0 。我该怎么做才能选择用户通过SQL分配的id,并将其作为userid放在记录条目上(ID在'CREATED'之后)?

此外,如果您看到可以对表格进行任何其他优化,请随时告诉我:D

4 个答案:

答案 0 :(得分:16)

  OP的评论:
  我以前怎么做呢,你呢?

您可以找到要分配给新记录的当前auto_increment值 并在before触发器中使用相同的内容作为user_records表的父用户ID 您必须查询information_schema.tables表以查找值。

示例

use `gknet`;

delimiter $$

drop trigger if exists before_create_user; $$

create definer=`root`@`localhost` trigger `before_create_user` 
       before insert on `users` 
for each row begin
  declare fk_parent_user_id int default 0;

  select auto_increment into fk_parent_user_id
    from information_schema.tables
   where table_name = 'users'
     and table_schema = database();

  insert into user_records ( action, userid, timestamp )
         values ( 'created', fk_parent_user_id, now() );
end;

$$

delimiter ;

答案 1 :(得分:3)

将触发器更改为after insert而不是before insert,并使用NEW获取最后插入的ID

USE `gknet`;
DELIMITER $$
CREATE DEFINER=`root`@`localhost` 
TRIGGER `after_create_user` AFTER INSERT ON `users` 
FOR EACH ROW 
BEGIN
INSERT INTO user_records (action, userid, timestamp)
  VALUES ('CREATED', NEW.ID, NOW() );
END; $$

答案 2 :(得分:1)

  

请在插入和更新后使用

不要将auto_increment设置为您想要显式操作的任何列。这可能会混淆发动机并导致严重问题。如果没有用于主键的列是auto_increment,则可以通过触发器对它们执行任何操作。如果它们违反了主键的强制性单一性,则肯定会拒绝生成的值。

答案 3 :(得分:0)

也许这个解决方案可以

  BEGIN 
  DECLARE id int;
  SELECT MAX(table_id) 
         FROM table 
         INTO id;

     IF id IS NULL THEN 
        SET NEW.column=(CONCAT('KTG',1));
     ELSE
     SET NEW.column=(CONCAT('KTG',id+1));
    END IF;

   END