我想要有一个触发执行下列操作插入记录:

 # pseudocode
 if new.group_id is null
    set new.group_id = new.id
 else
    # don't touch it
 end

更清楚:说我有一个表三列: id 主键, group_id int, value varchar。

当我插入 group_id 这样的:

INSERT INTO table(value, group_id) VALUES ('a', 10)

我想要有:

id | group_id | value
---+----------+------
 1 |       10 | a

但是,当我忽略 group_id:

INSERT INTO table(value) VALUES ('b')

它应当自动设定为 id 这个记录:

id | group_id | value
---+----------+------
 2 |        2 | b

它是可能带有触发?(我知道我可以更新的记录之后插入的,但具有触发,将会更好。)

有帮助吗?

解决方案

我不知道的任何方式做到这一声明中,甚至采用一种触发。

触发解决方案,@幸运的建议将会看起来像这MySQL:

CREATE TRIGGER MyTrigger BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
  SET NEW.group_id = COALESCE(NEW.group_id, NEW.id);
END

然而,有一个问题。在 BEFORE INSERT 阶段,自动生成的 id 值没有产生。所以如果 group_id 是空的,它默认 NEW.id 这始终是0.

但是,如果你改变这个触发器火期间 AFTER INSERT 相,所以你有权访问所产生的价值 NEW.id, 你不可以修改列价值观。

MySQL不支持表达式 DEFAULT 列,所以你不能宣布这种行为表中的定义。

唯一的解决办法是要做的 INSERT, ,然后立即做一个 UPDATE 改变的 group_id 如果它没有设置。

INSERT INTO MyTable (group_id, value) VALUES (NULL, 'a');
UPDATE MyTable SET group_id = COALESCE(group_id, id) WHERE id = LAST_INSERT_ID();

其他提示

我在这里回答,正如接受的答案 Bill Karwin 所述:

  

在BEFORE INSERT阶段,自动生成的id值尚未出现   生成了。因此,如果group_id为null,则默认为NEW.id   总是0。


我有一个答案 - 对于OP(以及来访的访客),这里有几点: 您无法更新触发器调用位置的表格,因为您将获得错误1442

Error Code: 1442
Can't update table 'MyTable' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

1.更新新行 使用 BEFORE INSERT ON 触发器,这样就可以更新新行的所有字段,可以通过NEW运算符访问,即

set NEW.group_id = NEW.id

2.插入前获取auto_increment值

SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='MyTable'

总结一下 - 'd的触发器SQL如下:

DELIMITER //
DROP TRIGGER IF EXISTS MyTrigger//
CREATE TRIGGER MyTrigger BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
    IF new.group_id IS NULL
        set @auto_id := (SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES
                         WHERE TABLE_NAME='MyTable' AND TABLE_SCHEMA=DATABASE() ); 
        set NEW.group_id = @auto_id;
    ENF IF;
END;
//
DELIMITER ;

这对我有用

DELIMITER $
CREATE TRIGGER `myTriggerNameHere`
BEFORE INSERT ON `table` FOR EACH ROW
BEGIN
    SET NEW.group_id = IF(NEW.group_id IS NULL, LAST_INSERT_ID()+1, NEW.group_id);
END;
$
DELIMITER ;

我相信这对你有用

我有两张桌子

test_b: a_id, value
test_c: a_id, value

这是插入测试b的触发器。它检查a_id是否为null,如果是,则插入0

CREATE TRIGGER test_b AFTER INSERT ON test_b
  FOR EACH ROW 
    INSERT INTO test_c (a_id, value) VALUES (IFNULL(NEW.a_id, 0),NEW.value)

此触发器应该按照您的要求执行。

   CREATE TRIGGER mytrigger BEFORE INSERT ON mytable
          IF new.group_id IS NULL
            SET new.group_id = new.id
          END IF
      END;

它是从 MYSQL文档中的一个非常相似的示例中复制而来的页面。

在这种情况下,触发器似乎有些过分。只需应用默认值。

CREATE TABLE `test` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `value` varchar(100) NOT NULL,
    `group_id` TINYINT(3) UNSIGNED NOT NULL DEFAULT '2'
)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top