0

MySQL でトリガーを使用して、次のことを行います。

新しいクライアントをクライアント テーブルに追加すると、「Client-Type」テーブルに一連のエントリが作成され、クライアント ID が一連のタイプ ID (client1、type1 client1、type2) にリンクされます。

ただし、トリガーが実行されると、データベースは最後のタイプのエントリを 2 回挿入します。したがって、最後の 2 つのエントリは (client1, type9 client1, type9) です。

トリガーコードは次のとおりです。

AFTER INSERT ON `nmsTicket`.`client`
FOR EACH ROW
BEGIN

   DECLARE done BOOLEAN DEFAULT 0;
   DECLARE a CHAR(2);

   DECLARE types CURSOR
   FOR
   SELECT typeID FROM type;

   DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

   OPEN types;


 REPEAT
      FETCH types INTO a;



       INSERT INTO clientType(id_type, id_client) VALUES (a,new.idClient);

   UNTIL done END REPEAT;

   CLOSE types;

何度か確認しましたが、なぜこのような動作をするのかわかりません。最後のエントリより前のすべてのエントリは正常に機能します。

ポインタはありますか?

4

1 に答える 1

0

トリガーでカーソルを使用している理由がわかりません。絶対に必要な場合を除き、これは避ける必要があります (たとえば、大量のデータを配信するクエリの最適な MySQL 設定を参照してください) 。

以下は、カーソルの代わりにクロス結合を使用する簡単な例 (参照整合性を除く) です。さらに、client_types テーブルでサロゲート主キーを使用しているのではなく、代わりに複合主キーを使用していることに気付くでしょう。これにより、データの整合性が強化されます。

スキーマ

drop table if exists client_type; --your type table
create table client_type
(
type_id tinyint unsigned not null auto_increment primary key,
name varchar(255) unique not null
)
engine=innodb;

drop table if exists client;
create table client
(
client_id int unsigned not null auto_increment primary key,
name varchar(255) not null
)
engine=innodb;

drop table if exists client_types; -- your clienttype table
create table client_types
(
client_id int unsigned not null,
type_id tinyint unsigned not null,
primary key (client_id, type_id) -- ** note use of composite primary key **
)
engine=innodb;

delimiter #

create trigger client_after_ins_trig after insert on client
for each row
begin

insert into client_types (client_id, type_id) 
select
 c.client_id,
 ct.type_id
from
 client c
cross join client_type ct
where
 c.client_id = new.client_id
order by
 ct.type_id;

end#

delimiter ;

テスト

mysql> insert into client_type (name) values ('type one'),('type two'),('type three');
Query OK, 3 rows affected (0.03 sec)

mysql> insert into client (name) values ('client A'),('client B');
Query OK, 2 rows affected (0.04 sec)

mysql> select * from client_type;
+---------+------------+
| type_id | name       |
+---------+------------+
|       1 | type one   |
|       3 | type three |
|       2 | type two   |
+---------+------------+
3 rows in set (0.00 sec)

mysql> select * from client;
+-----------+----------+
| client_id | name     |
+-----------+----------+
|         1 | client A |
|         2 | client B |
+-----------+----------+
2 rows in set (0.00 sec)

mysql> select * from client_types;
+-----------+---------+
| client_id | type_id |
+-----------+---------+
|         1 |       1 |
|         1 |       2 |
|         1 |       3 |
|         2 |       1 |
|         2 |       2 |
|         2 |       3 |
+-----------+---------+
6 rows in set (0.00 sec)

お役に立てれば :)

于 2012-04-12T09:41:38.780 に答える