1

可能な限り簡単な言葉で言えば、実際にトリガーに設定されている行を削除することは可能ですか。つまり、トリガーがあり、AFTER INSERT ON <table2>トリガー内にSQLがありますINSERT/UPDATE別の<table1>( a に基づくWHERE)、そして最終的にエントリを削除する傾向があります/の行 (基本的にトリガーを起動した行)。

トリガー SQL:

DELIMITER ||
DROP TRIGGER IF EXISTS trg_adddata_tmp ||
CREATE TRIGGER trg_adddata_tmp
AFTER INSERT ON adddata_tmp
FOR EACH ROW 
    BEGIN
        IF EXISTS (SELECT * FROM adddata WHERE data_id = new.data_id AND account_name = new.account_name) THEN
            UPDATE adddata SET data_id = new.data_id, account_name = new.account_name, user_name = new.user_name, first_name = new.first_name, last_name = new.last_name WHERE data_id = new.data_id AND account_name = new.account_name;
        ELSE
            INSERT INTO adddata (data_id, account_name, user_name, first_name, last_name)
            VALUES(new.data_id, new.account_name, new.user_name, new.first_name, new.last_name);
        END IF;
        DELETE FROM adddata_tmp WHERE id = new.id;
    END;
||  

DELETE(のすぐ上)がなければEND;、トリガーは正常に動作します-UPDATEそうでなければ存在する場合INSERT- withDELETEステートメントは次のエラーを返します:

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

ちなみに、エラーは一目瞭然ですが、これが可能かどうかを確認したかったのですが、そうでない場合は、他の方法である可能性があります。つまり、adddata_tmpテーブルをすべて空にする (またはクリーンアップする) 必要があります。時間(データをメインテーブルにINSERTコピーする場合)adddata

私が念頭に置いている 1 つのアイデアは、 を使用して、いくつかのフィールドに基づいてEVENTをクリーンアップすることです。これは、トリガーの最後のステートメントとして ( の代わりに) 設定されます。adddata_tmpstatusDELETE

4

1 に答える 1

1

いいえ、トリガーでこれを行うことはできません。ドキュメントには次のように記載されています。

ストアド関数またはトリガーは、関数またはトリガーを呼び出したステートメントによって (読み取りまたは書き込みのために) 既に使用されているテーブルを変更できません。

テーブルを常に空にする必要がある場合adddata_tmpは、トリガーをまったく記述しません。代わりにadddata、データを に挿入しようとするスクリプト/サービスの更新ロジックを移動することをお勧めしadddata_tmpます。

アップデート

一括挿入を行っていて、(adddata_tmpテーブル内の) データが他の場所で使用されていない場合は、テーブルをクリーンアップする cron ジョブを作成できます (つまり、10 分ごとに実行されるジョブ)。また、この場合はTRUNCATE(よりも) 効率的です。DELETE

于 2017-06-13T07:27:20.050 に答える