mysql触发器问题

时间:2021-02-15 10:58:36
有个表test,表test有个触发器 ttest
在ttest里面需要update一个字段。


在触发器中更改本表字段内容该如何做?

还是这个操作不适合用触发器来做呢?

ERROR 1442 (HY000): Can't update table 'test' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

18 个解决方案

#1


在触发器中更改本表字段内容该如何做?
MYSQL TRIGGER中,不允许对本表进行操作

你要达到什么目的,举例说明

#2




触发器中不可以对本表中进行update 的操作,这是MySQL的限制。或许有其它的方法可以实现你的需求。

#3


表中,有一字段插入时候要看看是不是符合要求
如果符合的时候,需要在这个表更新另外一个字段

CREATE TABLE `test` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `ip` bigint(20) default NULL,
  `mask` bigint(20) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM;

CREATE TABLE `test1` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `ip` bigint(20) default NULL,
  `NewField` varchar(255) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM;

CREATE TRIGGER `ok`.`asdf` AFTER INSERT ON `ok`.`test1`
  FOR EACH ROW begin
declare lastid int;
declare insertip bigint;
declare inips int;
select last_insert_id() into lastid;
select ip into insertip from test1 where id = lastid;
select count(*) into inips from test where ((ip & mask) = (insertip & mask));
if inips > 0
then
    update test1 set NewField = 'ok!';

end if;
end;


#4



try:
before insert:
select ip into insertip from test1 where id = newid.;
select count(*) into inips from test where ((ip & mask) = (new.id & mask));
if inips > 0
then
    set NewField = 'ok!';

end if;
end;

#5




估计你是想要实现这个。 你原来的是更新表中所有记录的NewField = 'ok!';

CREATE TRIGGER `ok`.`asdf` AFTER INSERT ON `ok`.`test1`
  FOR EACH ROW 
begin
declare lastid int;
declare insertip bigint;
declare inips int;
select last_insert_id() into lastid;
select ip into insertip from test1 where id = lastid;
select count(*) into inips from test where ((ip & mask) = (insertip & mask));
if inips > 0 then
    set New.NewField = 'ok!';
end if;
end;

#6


哦,这里有点错,
我原来的意思是:

update test1 set NewField = 'ok' where id = lastid;

#7


你应该是自己触发自己吧?

#8


是的,是这个想法的!

#9




mysql触发器问题
按五楼的代码问题还没解决?

你期望的结果是什么?更新表中所有记录的值?

#10


SQL execution error #1362. Response from the database:
Updating of NEW row is not allowed in after trigger


NEW关键字是不能用在 after trigger的

#11


我只是想更新新插入那条数据的值

#12


引用 10 楼 hzcenter 的回复:
SQL codeSQL execution error #1362. Response from the database:
Updating of NEW row is not allowed in after trigger
 
  
 NEW关键字是不能用在 after trigger的

对,只能在before trigger中,4楼的代码如何?

#13




你到现在才说出错误。 6楼以上谁能猜出你的问题有没有已经解决?

改成 before 就行了,因为AFTER的时候,不能再对NEW。*的内容进行修改。

mysql> CREATE TABLE `test1` (
    ->   `id` int(11) unsigned NOT NULL auto_increment,
    ->   `ip` bigint(20) default NULL,
    ->   `NewField` varchar(255) default NULL,
    ->   PRIMARY KEY  (`id`)
    -> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.50 sec)

mysql> delimiter //
mysql> CREATE TRIGGER `asdf` BEFORE INSERT ON `test1`
    ->   FOR EACH ROW
    -> begin
    ->     declare lastid int;
    ->     declare insertip bigint;
    ->     declare inips int;
    ->     select last_insert_id() into lastid;
    ->     select ip into insertip from test1 where id = lastid;
    ->     select count(*) into inips from test where ((ip & mask) = (insertip & mask));
    ->     if inips > 0 then
    ->         set New.NewField = 'ok!';
    ->     end if;
    -> end;
    -> //
Query OK, 0 rows affected (0.09 sec)

mysql> delimiter ;
mysql>

#14


before是在插入之前更新

安照我的理解就是数据插到表之前的一个触发响应,这个时候表中应该还没有这条数据吧?

如果理解错误请指正!

#15


mysql> select * from test1 order by id desc limit 1;
+----+------------+----------+
| id | ip         | NewField |
+----+------------+----------+
|  5 | 2043752021 | NULL     |
+----+------------+----------+
1 row in set (0.00 sec)

mysql> insert into test1 (ip) values(2043752021);
Query OK, 1 row affected, 1 warning (0.02 sec)

mysql> select * from test1 order by id desc limit 2;
+----+------------+----------+
| id | ip         | NewField |
+----+------------+----------+
|  6 | 2043752021 | NULL     |
|  5 | 2043752021 | NULL     |
+----+------------+----------+
2 rows in set (0.00 sec)


第六条数据并没有更新NewField的内容阿

#16


哦,是declare inips int;的问题,应该改称bigint。
int太小了。
现在ok了!谢谢各位!加100分给大家!

#17


代码是什么?自己解决更好 

#18


mysql> CREATE TABLE `test1` (
    ->   `id` int(11) unsigned NOT NULL auto_increment,
    ->   `ip` bigint(20) default NULL,
    ->   `NewField` varchar(255) default NULL,
    ->   PRIMARY KEY  (`id`)
    -> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.50 sec)

mysql> delimiter //
mysql> CREATE TRIGGER `asdf` BEFORE INSERT ON `test1`
    ->   FOR EACH ROW
    -> begin
    ->     declare lastid int;
    ->     declare insertip bigint;
    ->     declare inips  bigint;//原来这里是int类型的。数据不能超过2147483647
    ->     select last_insert_id() into lastid;
    ->     select ip into insertip from test1 where id = lastid;
    ->     select count(*) into inips from test where ((ip & mask) = (insertip & mask));
    ->     if inips > 0 then
    ->         set New.NewField = 'ok!';
    ->     end if;
    -> end;
    -> //
Query OK, 0 rows affected (0.09 sec)

mysql> delimiter ;
mysql>

触发起是触发了。但是因为数据类型问题,导致select count(*) into inips from test where ((ip & mask) = (insertip & mask));
这条语句为false。

#1


在触发器中更改本表字段内容该如何做?
MYSQL TRIGGER中,不允许对本表进行操作

你要达到什么目的,举例说明

#2




触发器中不可以对本表中进行update 的操作,这是MySQL的限制。或许有其它的方法可以实现你的需求。

#3


表中,有一字段插入时候要看看是不是符合要求
如果符合的时候,需要在这个表更新另外一个字段

CREATE TABLE `test` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `ip` bigint(20) default NULL,
  `mask` bigint(20) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM;

CREATE TABLE `test1` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `ip` bigint(20) default NULL,
  `NewField` varchar(255) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM;

CREATE TRIGGER `ok`.`asdf` AFTER INSERT ON `ok`.`test1`
  FOR EACH ROW begin
declare lastid int;
declare insertip bigint;
declare inips int;
select last_insert_id() into lastid;
select ip into insertip from test1 where id = lastid;
select count(*) into inips from test where ((ip & mask) = (insertip & mask));
if inips > 0
then
    update test1 set NewField = 'ok!';

end if;
end;


#4



try:
before insert:
select ip into insertip from test1 where id = newid.;
select count(*) into inips from test where ((ip & mask) = (new.id & mask));
if inips > 0
then
    set NewField = 'ok!';

end if;
end;

#5




估计你是想要实现这个。 你原来的是更新表中所有记录的NewField = 'ok!';

CREATE TRIGGER `ok`.`asdf` AFTER INSERT ON `ok`.`test1`
  FOR EACH ROW 
begin
declare lastid int;
declare insertip bigint;
declare inips int;
select last_insert_id() into lastid;
select ip into insertip from test1 where id = lastid;
select count(*) into inips from test where ((ip & mask) = (insertip & mask));
if inips > 0 then
    set New.NewField = 'ok!';
end if;
end;

#6


哦,这里有点错,
我原来的意思是:

update test1 set NewField = 'ok' where id = lastid;

#7


你应该是自己触发自己吧?

#8


是的,是这个想法的!

#9




mysql触发器问题
按五楼的代码问题还没解决?

你期望的结果是什么?更新表中所有记录的值?

#10


SQL execution error #1362. Response from the database:
Updating of NEW row is not allowed in after trigger


NEW关键字是不能用在 after trigger的

#11


我只是想更新新插入那条数据的值

#12


引用 10 楼 hzcenter 的回复:
SQL codeSQL execution error #1362. Response from the database:
Updating of NEW row is not allowed in after trigger
 
  
 NEW关键字是不能用在 after trigger的

对,只能在before trigger中,4楼的代码如何?

#13




你到现在才说出错误。 6楼以上谁能猜出你的问题有没有已经解决?

改成 before 就行了,因为AFTER的时候,不能再对NEW。*的内容进行修改。

mysql> CREATE TABLE `test1` (
    ->   `id` int(11) unsigned NOT NULL auto_increment,
    ->   `ip` bigint(20) default NULL,
    ->   `NewField` varchar(255) default NULL,
    ->   PRIMARY KEY  (`id`)
    -> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.50 sec)

mysql> delimiter //
mysql> CREATE TRIGGER `asdf` BEFORE INSERT ON `test1`
    ->   FOR EACH ROW
    -> begin
    ->     declare lastid int;
    ->     declare insertip bigint;
    ->     declare inips int;
    ->     select last_insert_id() into lastid;
    ->     select ip into insertip from test1 where id = lastid;
    ->     select count(*) into inips from test where ((ip & mask) = (insertip & mask));
    ->     if inips > 0 then
    ->         set New.NewField = 'ok!';
    ->     end if;
    -> end;
    -> //
Query OK, 0 rows affected (0.09 sec)

mysql> delimiter ;
mysql>

#14


before是在插入之前更新

安照我的理解就是数据插到表之前的一个触发响应,这个时候表中应该还没有这条数据吧?

如果理解错误请指正!

#15


mysql> select * from test1 order by id desc limit 1;
+----+------------+----------+
| id | ip         | NewField |
+----+------------+----------+
|  5 | 2043752021 | NULL     |
+----+------------+----------+
1 row in set (0.00 sec)

mysql> insert into test1 (ip) values(2043752021);
Query OK, 1 row affected, 1 warning (0.02 sec)

mysql> select * from test1 order by id desc limit 2;
+----+------------+----------+
| id | ip         | NewField |
+----+------------+----------+
|  6 | 2043752021 | NULL     |
|  5 | 2043752021 | NULL     |
+----+------------+----------+
2 rows in set (0.00 sec)


第六条数据并没有更新NewField的内容阿

#16


哦,是declare inips int;的问题,应该改称bigint。
int太小了。
现在ok了!谢谢各位!加100分给大家!

#17


代码是什么?自己解决更好 

#18


mysql> CREATE TABLE `test1` (
    ->   `id` int(11) unsigned NOT NULL auto_increment,
    ->   `ip` bigint(20) default NULL,
    ->   `NewField` varchar(255) default NULL,
    ->   PRIMARY KEY  (`id`)
    -> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.50 sec)

mysql> delimiter //
mysql> CREATE TRIGGER `asdf` BEFORE INSERT ON `test1`
    ->   FOR EACH ROW
    -> begin
    ->     declare lastid int;
    ->     declare insertip bigint;
    ->     declare inips  bigint;//原来这里是int类型的。数据不能超过2147483647
    ->     select last_insert_id() into lastid;
    ->     select ip into insertip from test1 where id = lastid;
    ->     select count(*) into inips from test where ((ip & mask) = (insertip & mask));
    ->     if inips > 0 then
    ->         set New.NewField = 'ok!';
    ->     end if;
    -> end;
    -> //
Query OK, 0 rows affected (0.09 sec)

mysql> delimiter ;
mysql>

触发起是触发了。但是因为数据类型问题,导致select count(*) into inips from test where ((ip & mask) = (insertip & mask));
这条语句为false。