нет необходимости создавать еще одну таблицу, а max() будет иметь проблемы в связи с автоинкрементным значением таблицы, сделайте так:
CREATE TRIGGER trigger_name BEFORE INSERT ON tbl FOR EACH ROW
BEGIN
DECLARE next_id INT;
SET next_id = (SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='tbl');
SET NEW.field=next_id;
END
Я объявляю переменную next_id, потому что обычно она будет использоваться как-то иначе(*), но вы могли бы сделать прямо new.field=(select ...)
(*) To auto-name an image:
SET NEW.field = CONCAT('image_', next_id, '.gif');
(*) To create a hash:
SET NEW.field = CONCAT( MD5( next_id ) , MD5( FLOOR( RAND( ) *10000000 ) ) );
видя, что last_insert_id()
не работал бы в этом случае, да, триггер будет единственным способом выполнить это.
я действительно спрашиваю меня хотя: Для чего Вы нуждаетесь в этой функциональности? Почему Вы храните пользовательский идентификатор дважды? Лично, мне не нравится хранить избыточные данные как это, и я, вероятно, решил бы это в коде приложения путем создания, что зловещий default_assignment
столбец NULL и использование идентификатора пользователя в моем коде приложения, если бы default_assignment
было ПУСТЫМ.
На самом деле я просто пытался сделать то же самое, что было предложено выше. Но кажется, что Mysql doesent генерирует вставленный идентификатор до того, как строка действительно будет зафиксирована. Таким образом, NEW.userid всегда будет возвращать 0 в триггере Before insert.
Вышеупомянутое также не будет работать, если это не триггер BEFORE INSERT, поскольку вы не можете обновлять значения в запросе AFTER INSERT.
Из сообщения на форуме Mysql. кажется, единственный способ справиться с этим - использовать дополнительную таблицу в качестве последовательности. Чтобы ваш триггер мог получать значения из внешнего источника.
CREATE TABLE `lritstsequence` (
`idsequence` int(11) NOT NULL auto_increment,
PRIMARY KEY (`idsequence`)
) ENGINE=InnoDB;
CREATE TABLE `lritst` (
`id` int(10) unsigned NOT NULL auto_increment,
`bp_nr` decimal(10,0) default '0',
`descr` varchar(128) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `dir1` (`bp_nr`)
) ENGINE=InnoDB;
DELIMITER $$
DROP TRIGGER /*!50032 IF EXISTS */ `lritst_bi_set_bp_nr`$$
CREATE TRIGGER `lritst_bi_set_bp_nr` BEFORE INSERT ON `lritst`
FOR EACH ROW
BEGIN
DECLARE secuencia INT;
INSERT INTO lritstsequence (idsequence) VALUES (NULL);
SET secuencia = LAST_INSERT_ID();
SET NEW.id = secuencia;
SET NEW.bp_nr = secuencia;
END;$$
DELIMITER ;
INSERT INTO lritst (descr) VALUES ('test1');
INSERT INTO lritst (descr) VALUES ('test2');
INSERT INTO lritst (descr) VALUES ('test3');
SELECT * FROM lritst;
Result:
id bp_nr descr
------ ------ ------
1 1 test1
2 2 test2
3 3 test3
Это скопировано с форумов.
Единственное, что я обнаружил, что решило бы эту проблему без дополнительной таблицы, - это вычислить себе следующее число и поместить его в обязательные поля.
CREATE TABLE `Temp` (
`id` int(11) NOT NULL auto_increment,
`value` varchar(255) ,
PRIMARY KEY (`idsequence`)
) ENGINE=InnoDB;
CREATE TRIGGER temp_before_insert BEFORE INSERT ON `Temp`
FOR EACH ROW
BEGIN
DECLARE m INT;
SELECT IFNULL(MAX(id), 0) + 1 INTO m FROM Temp;
SET NEW.value = m;
-- NOT NEEDED but to be save that no other record can be inserted in the meanwhile
SET NEW.id = m;
END;