0

NEW/OLD データをファイル名なしで一時テーブルに入れる方法。トリガーを作成しようとしましたが、次のような手順を実行しましたが、失敗しました:


CREATE TRIGGER `after_insert` AFTER INSERT
ON `master`
FOR EACH ROW BEGIN
    CREATE TEMPORARY TABLE after_insert_trigger_temp_table ENGINE=MEMORY 
    AS (SELECT NEW.*);
    CALL after_insert_action();
END$$


CREATE PROCEDURE `after_insert_action`()
BEGIN
    INSERT INTO `slave` (`name`,`detail`)
    SELECT `name`,`detail` FROM after_insert_trigger_temp_table;
END$$

4

1 に答える 1

3

と書かれている部分が見えますFOR EACH ROW...

次のステートメントFOR EACH ROWは、トリガーがアクティブになるたびに実行するステートメントを定義します。これは、トリガーを実行するステートメントの影響を受ける行ごとに 1 回発生します。-- http://dev.mysql.com/doc/refman/5.5/en/trigger-syntax.html (強調を追加)

したがって、トリガーを使用してテーブルに挿入される行ごとに新しい一時テーブルを作成し、何らかの方法ですべての列にアクセスすることを提案していますNEW*そのテーブルに挿入し、次にストアド プロシージャを呼び出し、元のテーブルにあると思われる一時テーブルから 2 つの列を選択して別のテーブルに挿入します。1回のクエリまたは1回のセッションで複数の行をテーブルに挿入した場合、同じ名前の一時テーブルを作成しようとするため、一時テーブルはもちろん削除する必要があります。セッションによってすでに所有されています。

トリガーまたはドキュメントで OLD.* または NEW.* キャッチオールに遭遇したことは一度もありません。とにかく、2 つの列名を入力することを回避するか、変更する機能を回避する以外に、何を達成しようとしているのかはまったく明確ではありません。このトリガーを更新せずに、ストアド プロシージャで追跡しているもの。

ただし、トリガーに関して留意する必要がある重要な設計要素は、この規則に従わないとパフォーマンスの問題が発生する可能性が高いため、可能な限り効率的に実行する必要があるということです。

質問の詳細に基づいて一時テーブルが意味をなさないため、いくつかの代替アプローチが思い浮かびます。

オプション1:

CREATE TRIGGER `after_insert` AFTER INSERT ON `master` FOR EACH ROW 
BEGIN
    INSERT INTO `slave` (`name`,`detail`) VALUES (NEW.`name`,NEW.`detail`);
END $$

オプション 2:

CREATE TRIGGER `after_insert` AFTER INSERT ON `master` FOR EACH ROW 
BEGIN
    CALL after_insert_action(NEW.`name`,NEW.`detail`);
END $$


CREATE PROCEDURE `after_insert_action`(in new_name TEXT, in new_detail TEXT)
# you may want to use more appropriate datatypes instead of TEXT
# but this should work as written as long as those columns are no larger than TEXT
BEGIN
    INSERT INTO `slave` (`name`,`detail`) VALUES (new_name, new_detail);
END$$
于 2013-02-23T20:12:26.623 に答える