2014-06-25 10 views
7

La tabella utenti:Utilizzo del valore di incremento automatico in MYSQL prima di inserire Trigger?

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; 

La tabella 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; 

La prima trigger di inserimento nella tabella degli utenti:

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 

Fondamentalmente, il mio problema qui è che il grilletto quando provo a inserire l'id dell'utente che viene automaticamente assegnato da MySQL (PK, NN, Auto-Increment), inserisce solo 0 per userid nella scheda user_records le. Come dovrei farlo in modo che selezionasse l'id che l'utente viene assegnato da SQL e lo inserisca come userid nella voce records (dove l'ID è giusto dopo 'CREATED')?

Inoltre, se si vede tutti altre ottimizzazioni che potrebbero essere fatte sui tavoli, non esitate a farmi sapere: D

risposta

11

PO:
Come potrei farlo prima, tu?

Potete trovare valore attuale auto_increment che deve essere assegnato a un nuovo record.
E utilizzare lo stesso nel trigger before come ID utente padre per la tabella user_records.
È necessario interrogare la tabella information_schema.tables per trovare il valore.

Esempio:

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

Grazie! Vorrei upvote ma ho bisogno di più rappresentanti! –

+0

Grazie per aver fornito la soluzione –

1

Cambiare il grilletto per after insert invece di before insert e utilizzare NEW di ottenere l'ultimo ID inserito

commento
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

Come dovrei farlo prima, tu? –

+0

Con before insert non ha senso, una volta inserito, solo allora si otterrà l'iduser dalla tabella utente. Se si utilizza prima dell'inserimento, è necessario selezionare l'ultimo id dalla tabella utente, incrementarlo di uno e quindi inserirlo nella tabella e questo non è un modo corretto di fare. Prima di inserire è meglio per quando si controlla i dati in arrivo e quindi modificare alcuni valori in base alle condizioni prima di inserirlo. –

+2

@AbhikChakraborty: No, non è necessario per l'incremento manuale del valore. È possibile ottenere ciò leggendo il prossimo valore auto_increment disponibile da assegnare. Controlla la mia risposta. –

Problemi correlati