这是我的架构:
我正在尝试插入“桌面”或“笔记本电脑”插入从“计算机”自动生成的ID。这很有效。
我的问题是当我插入任一表时,我无法选择last_insert_id();
我做错了吗?我试图将id一直传递给我的应用程序,以便进一步处理。选择MAX(id)不是有效的解决方案。我的SQL连接生成一个insert语句,触发器不应该破坏该功能......
Use test;
CREATE TABLE `laptops` (
`id` int(11) NOT NULL,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=innodb DEFAULT CHARSET=utf8;
CREATE TABLE `desktops` (
`id` int(11) NOT NULL,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=innodb DEFAULT CHARSET=utf8;
CREATE TABLE `computers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=innodb DEFAULT CHARSET=utf8;
CREATE TRIGGER `laptops_BINS` BEFORE INSERT ON `laptops` FOR EACH ROW
BEGIN
IF (EXISTS(SELECT id FROM laptops WHERE name = NEW.name)) THEN
SET NEW.id = NULL;
ELSE
INSERT INTO computers (type) VALUES ('laptop');
SET NEW.id = LAST_INSERT_ID();
SET NEW.id = LAST_INSERT_ID(NEW.id);
END IF;
END
CREATE TRIGGER `desktop_BINS` BEFORE INSERT ON `desktops` FOR EACH ROW
BEGIN
IF (EXISTS(SELECT id FROM desktops WHERE name = NEW.name)) THEN
SET NEW.id = NULL;
ELSE
INSERT INTO computers (type) VALUES ('desktop');
SET NEW.id = LAST_INSERT_ID();
SET NEW.id = LAST_INSERT_ID(NEW.id);
END IF;
END
INSERT INTO laptops (name) VALUES ('laptop1');
INSERT INTO laptops (desktop) VALUES ('desktop1');
INSERT INTO laptops (name) VALUES ('laptop2');
INSERT INTO laptops (desktop) VALUES ('desktop2');
SELECT last_insert_id();
期待4,实际上是0。
有关如何修复触发器的任何想法?也许有人可以帮我格式化AFTER_INSERT语句来修复last_insert_id?
我尝试将值设置为自动递增,并且笔记本电脑和桌面表中的唯一值都不会解决问题。
答案 0 :(得分:1)
而不是试图处理'last_insert_id'的'混乱'。我决定将表格结构更改为更“通用”的格式。 这就是将'laptops'和'desktops'表改为'auto_increment'键。这会将“计算机”表更改为“笔记本电脑”或“桌面”和“computer_type”中的主键“computer_id”。
以下是表结构和触发器。
已在windows xp上的mysql 5.5.16上测试过。
CREATE TABLE `laptops` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
CREATE TABLE `desktops` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
CREATE TABLE `computers` (
`computer_id` int(11) NOT NULL,
`computer_type` varchar(45) NOT NULL,
PRIMARY KEY (`computer_id`,`computer_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DELIMITER $$
USE `testmysql`$$
DROP TRIGGER /*!50032 IF EXISTS */ `laptop_bins`$$
CREATE
/*!50017 DEFINER = 'test'@'localhost' */
TRIGGER `laptop_bins` AFTER INSERT ON `laptops`
FOR EACH ROW BEGIN
INSERT INTO computers (computer_id, computer_type ) VALUES (new.id, 'laptop');
END;
$$
DELIMITER ;
DELIMITER $$
USE `testmysql`$$
DROP TRIGGER /*!50032 IF EXISTS */ `desktop_bins`$$
CREATE
/*!50017 DEFINER = 'test'@'localhost' */
TRIGGER `desktop_bins` AFTER INSERT ON `desktops`
FOR EACH ROW BEGIN
INSERT INTO computers (computer_id, computer_type ) VALUES (new.id, 'desktop');
END;
$$
DELIMITER ;
示例查询和输出:
INSERT INTO laptops (NAME) VALUES ('laptop1');
INSERT INTO desktops (NAME) VALUES ('desktop1');
INSERT INTO laptops (NAME) VALUES ('laptop2');
INSERT INTO desktops (NAME) VALUES ('desktop2');
Laptops:
id name
------ ---------
1 laptop1
2 laptop2
Desktops:
id name
------ ----------
1 desktop1
2 desktop2
Computers:
computer_id computer_type
----------- ---------------
1 desktop
1 laptop
2 desktop
2 laptop
答案 1 :(得分:0)
这更符合要求而不是答案。
如果需要,我可以创建代码。这里的代码并不是很多代码。
问题是在同步中维护其他数据库中的表,而不进行大量的重复工作。
我的建议:
在'computers'数据库中 - 有一个'computers_new'表,由'after insert'触发器插入并保存相关的密钥信息。包括“未处理”列。
然后我会定期运行脚本,或者在'computers_new'表更改时触发。它会:
1)将“未处理”的详细信息传输到另一个数据库中的“笔记本电脑”,“桌面”表。
2)将转移的记录标记为已处理。
优点:
很多小块工作。 通过使用交易,它是可靠的。
缺点。
确保表格同步。