7

BEFORE INSERT TRIGGER列の値を計算するために使用される がありAUTO_INCREMENTます ( id_2)。

id_1 | id_2 | data
1    | 1    | 'a'
1    | 2    | 'b'
1    | 3    | 'c'
2    | 1    | 'a'
2    | 2    | 'b'
2    | 3    | 'c'
2    | 4    | 'a'
3    | 1    | 'b'
3    | 2    | 'c'

PRIMARY(id_1, id_2) があり、InnoDB を使用しています。以前は、テーブルは MyISAM を使用していましたが、問題はありませんでしid_2た。さて、InnoDB に切り替えた後、同じことを行うためのトリガーがあります。AUTO_INCREMENTid_1id_2

SET @id = NULL;
SELECT COALESCE(MAX(id_2) + 1, 1) INTO @id FROM tbl WHERE id_1 = NEW.id_1;
SET NEW.id_2= @id;

これは完全に機能しますが、LAST_INSERT_ID()値が間違っている (0 を返す) ことを除きます。LAST_INSERT_ID()多くのコードは、正しいかどうかに依存しています。ただし、MySQL 5.0.12 以降、LAST_INSERT_IDTRIGGERS 内で行われた変更はグローバル値に影響しません。これをバイパスする方法はありますか?を呼び出してAFTER UPDATE TRIGGERを変更する を簡単に設定できますが、クライアント側は0 に設定されます。LAST_INSERT_IDLAST_INSERT_ID(NEW.id_2)LAST_INSERT_ID

LAST_INSERT_IDトリガー内で変更された状態を MySQL に強制的に維持させるための回避策はありますか? これをすぐにサポートする MyISAM に戻すかSELECT max(id_2) FROM tbl WHERE id_1 = :id、トランザクションの一部として別の行を実行して、見つかった行が以前に挿入された行になるようにする以外に、代替手段はありますか?

> SHOW CREATE TABLE tbl;

CREATE TABLE `tbl` (
   `id_1` int(11) NOT NULL,
   `id_2` int(11) NOT NULL,
   `data` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
   PRIMARY KEY (`id_1`,`id_2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

例:

INSERT INTO tbl (id_1, id_2, data) VALUES (1, NULL, 'd');
SELECT LAST_INSERT_ID();

最初のステートメントは、行1 | 4 | 'd'をテーブルに挿入します。2 番目のステートメントは を返します0が、返す必要があり4ます。

Ravinder Reddyの質問に応じて、システムに関する簡単な説明を追加します。

バスケットを含むテーブルがあり、項目を含む別のテーブル ( tbl) があります。バスケットはアプリケーションによって作成され、バスケットのテーブルから ID が割り当てられます。タスクは、id = のバスケットにアイテムを に挿入し、そのバスケットのスコープ内で一意の ID を割り当てることです。各アイテムには関連するものがあり、同じバスケット内で繰り返される場合があります。したがって、実際には、すべてのエントリを 1 つのバスケットに格納し、これらの個々のエントリを-ペアで参照 (および取得) できるようにしようとしています。AUTO_INCREMENTid_1tbldatadataid_1id_2

4

1 に答える 1