1

これを含むトリガーがあります:

SET v1 = CONCAT_WS(',',NEW.ID, NEW.Name, NEW.Type, NEW.Value);

これをこのようなものに簡略化して、新しい行全体を含めることはできますか?:

SET v1 = CONCAT_WS(',',NEW.*);

(上記のバリエーションを試しましたが、構文エラーが発生します)

ありがとう

4

1 に答える 1

0

いいえ、これを行う簡単な方法はありません。各列を参照する必要があります。

唯一の実際の回避策は、テーブルメタデータを使用して必要なステートメントを生成し、そのステートメントをプロシージャに含めることです。

可能であっても、TRIGGERでこれを動的に実行することは望ましくありません。

SELECT CONCAT('NEW.`',GROUP_CONCAT(c.column_name 
       ORDER BY ORDINAL_POSITION SEPARATOR '`,NEW.`'),'`')
  FROM information_schema.columns 
 WHERE table_schema = DATABASE() 
   AND table_name = 'mytable'

次のような文字列が表示されます。

NEW.`ID`,NEW.`Name`,NEW.`Type`,NEW.`Value`

そして、それをトリガー本体に貼り付けることができます。(もちろん、CONCATを拡張して行全体を生成することもできます。)

欠点は、新しい列がテーブルに追加されたときに、それらが自動的に含まれないことです。トリガーを変更する必要があります。列が削除または名前変更されると、トリガーは例外のスローを開始します。再びトリガーの修正が必要です。


アップデート

Q:この文字列をMySQLクエリに変換するにはどうすればよいですか?

@query = "CONCAT_WS(',','CCC','64',NEW.Record,NEW.ID,NEW.Name,NEW.User_ID,NEW.State_Record,NEW.Hash);"

私はそれをクエリに変換しません。これを、トリガーの元のステートメントと同じように、トリガーの本文の静的なコード行(二重引用符なし)として使用します。

SET v1 = CONCAT_WS(',','CCC','64',NEW.Record,NEW.ID,NEW.Name,NEW.User_ID,NEW.State_Record,NEW.Hash);

(その文字列で何をしようとしているのかは明確ではありませんでした。)

SELECTステートメントを作成しようとしている場合は、文字列の末尾からそのセミコロンを削除し、その上にSELECTキーワードを追加してみてください。しかし、私は新しいとは思いません。現在の行の列値への参照は、そのコンテキストで認識されます。それが起こるかもしれませんが、あなたはテストする必要があるでしょう。

そのようなことをする必要がある場合は、ユーザー変数を使用して行います。

SET @new_id = NEW.ID;
SET @new_name = NEW.Name;

SELECT @new_id, @new_name 

のようなクエリによって返される結果セットをどうするかは、私にはまったくわかりません。テーブルへの変更を監査しようとしている場合、標準的なパターンは、列値のINSERTを変更ログテーブルに実行することです。

INSERT INTO mytable_changelog (ID, Name) VALUES (NEW.ID, NEW.Name);

それは本当にあなたが達成しようとしていることに依存します。

于 2012-07-16T23:19:00.277 に答える