Mysql Trigger不会将last_insert_id()传递给连接

时间:2014-03-12 07:29:40

标签: mysql

这是我的架构:

我正在尝试插入“桌面”或“笔记本电脑”插入从“计算机”自动生成的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?

我尝试将值设置为自动递增,并且笔记本电脑和桌面表中的唯一值都不会解决问题。

2 个答案:

答案 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)将转移的记录标记为已处理。

优点:

很多小块工作。 通过使用交易,它是可靠的。

缺点。

确保表格同步。