2014-06-25 31 views
7

的用户表:在插入触发器之前在MYSQL中使用自动递增值?

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; 

的对用户表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,Auto-Increment)时,它只会在user_records选项卡中为userid放置0乐。我该怎么做,因此它会选择用户正在被SQL分配的id,并将其作为userid放入记录条目中(其中ID在'CREATED'之后)?

另外,如果你发现可以在表上进行任何其他优化,随时让我知道:d

回答

11

OP的评论:
如何将我之前做的,你是谁?

您可以找到当前要分配给新记录的auto_increment值。
并使用before触发器中的相同作为user_records表的父级用户标识。
您必须查询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 ; 
+0

谢谢!我会upvote,但我需要更多的代表! –

+0

感谢您提供解决方案 –

1

更改触发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; $$ 
+0

怎么会我之前做的,你是谁? –

+0

与之前插入它没有意义,一旦插入发生然后只有你会从用户表中获取iduser。如果您在插入前执行此操作,则需要从用户表中选择最后一个ID,然后将其添加到表中,然后插入表中,这不是一种正确的方法。插入之前,最好先检查传入数据,然后在插入之前根据条件更改一些值。 –

+2

@AbhikChakraborty:不,这个值不需要手动递增。您可以通过读取要分配的下一个可用auto_increment值来实现此目的。检查我的答案。 –