web-dev-qa-db-ja.com

1つのSQLステートメントを使用してMySQLデータベースのすべてのトリガーを削除するにはどうすればよいですか?

クローンを作成したDBがあり、すべてのログトリガーは元のスキーマのログテーブルを指します。それらをすべて再作成できるように、一度にすべてを削除する必要があります(数十個あります)。これを1つのコマンドでどのように行うことができますか?

29
Matt Gibson

これは古い質問ですが、それが私の検索でポップアップし続けるものなので、ここに解決策を投稿すると思いました。私の場合、完全なmysqldumpを持つ単一のファイルを作成する必要があり、その後、トリガーをすべてドロップしてから、それらをすべて追加し直します。トリガーのダンプを追加する前に、次のコマンドを使用してDROP TRIGGERステートメントをダンプに追加することでそれを行うことができました。

mysql -u [db user] -p[db password] --skip-column-names [db name] -e 'SHOW TRIGGERS;' | cut -f1 | sed -r 's/(.*)/DROP TRIGGER IF EXISTS \1;/' >> dump.sql

同じコマンドですべてのトリガーを実際にドロップするには(コメントで@Stephen Crosbyが述べているように)、これを次のようにMySQLにパイプで戻すことができます。

mysql -u [db user] -p[db password] --skip-column-names [db name] -e 'SHOW TRIGGERS;' | cut -f1 | sed -r 's/(.*)/DROP TRIGGER IF EXISTS \1;/' | mysql -u [db user] -p[db password] [db name]
28
SELECT Concat('DROP TRIGGER ', Trigger_Name, ';') FROM  information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = 'your_schema';

生成されたSQLをコピーして貼り付けます

すべてのデータベースからすべてのトリガーを削除する必要がある場合は、必ずmysqlスキーマを除外してください。

SELECT Concat('DROP TRIGGER ', EVENT_OBJECT_SCHEMA, '.', Trigger_Name, ';'), TRIGGER_NAME, EVENT_OBJECT_SCHEMA, EVENT_OBJECT_TABLE FROM  information_schema.TRIGGERS WHERE EVENT_OBJECT_SCHEMA <> 'mysql';
36
Lücks

残念ながら、これは通常のSQLステートメントまたはストアドプロシージャでは不可能です。

ソリューション

すべてのトリガーをドロップする最も簡単なソリューションは、bashスクリプトです。

echo "select concat('drop trigger ', trigger_name, ';')
  from information_schema.triggers where trigger_schema = 'your_database'" |
  mysql --defaults-extra-file=.mysql.conf --disable-column-names | 
  mysql --defaults-extra-file=.mysql.conf

これには、次のような資格情報ファイル(.mysql.conf)が必要です。

[client]
database=your_database
user=your_username
password=your_password

推論

ストアドプロシージャからトリガーを削除しようとすると失敗します。変数は文字列のみを保持でき、drop triggerはトリガー名を必要とする(トリガー名を含む文字列ではない)ため、これが起こると思います:

create procedure drop_a_trigger()
begin
  declare var1 varchar(1024);
  set var1 = "my_second_trigger";

  drop trigger my_first_trigger;       // OK
  drop trigger address_update_before;  // ERROR 1360 (HY000): Trigger does not exist

end //
delimiter ;

call drop_a_trigger();

MySQLフォーラムには、これに関する2つのスレッドがあります。

どちらも、ストアドプロシージャを使用しても効果がないという同じ結論に達します。

7
Ian Mackinnon

1つのSQLステートメントを使用してMySQLデータベースのすべてのトリガーを削除することはできません。

ただし、次のSQLコードを使用すると、すべての「DROP TRIGGER」ステートメントのリストを作成できます(replace<your_schema>)、スキーマ名、例:データベース名):

-- set `group_concat_max_len`
SET @@session.group_concat_max_len = @@global.max_allowed_packet;

-- select all the triggers and build the `DROP TRIGGER` SQL
-- replace <your_schema> with your schema name (e.g. your database name)
SELECT GROUP_CONCAT(sql_string SEPARATOR '\n')
FROM (
    SELECT CONCAT('DROP TRIGGER IF EXISTS `', TRIGGER_NAME, '`;') AS sql_string,'1'
    FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = '<your_schema>'
    ) AS sql_strings
GROUP BY '1';

前のクエリの結果は次のようなものを生成します。

DROP TRIGGER IF EXISTS `trigger1`;
DROP TRIGGER IF EXISTS `trigger2`;
(...)

そして、これらのSQLステートメントを使用して、最終的にすべてのトリガーを削除できます。

サーバーシステム変数 group_concat_max_len は、GROUP_CONCAT()関数の最大許容結果長(バイト単位)です。デフォルトは1024であるため、トリガーが多数ある場合に切り捨てられた結果を避けるために、デフォルトを増やす必要があります。サーバーシステム変数 max_allowed_pa​​cket の値を使用しましたが、通常は任意の大きな整数値で問題ありません。 この他の質問 を参照してください。

5
cgaldiolo
SELECT Trigger_Name
FROM `information_schema`.`TRIGGERS`
WHERE TRIGGER_SCHEMA = 'your_schema';

結果をクリップボードにコピー

変換Trigger_nameからDROP TRIGGER <trigger_name>; reg.expressionsで行の始まりと終わりに^およびSタグを使用する各トリガー

sQLスクリプトとして実行

3
user3155977

データベースをファイルにsqldumpする必要なく、クエリを使用してそれらを削除したい場合:

select concat('drop trigger ', trigger_name, ';') from information_schema.triggers where trigger_schema = 'your_schema';次に、結果をエクスポートする必要があり(CSVに保存するのが最も簡単です)、それらの結果でクエリを実行します。

0
Naguib Ihab

MAMPを使用するMAC:

受け入れられた回答に対して行う必要がある小さな調整がいくつかあります。まず、MAMPでmysqlをターゲットにする必要があります。第二に、sed -rはMacでは機能しません。sed -E代わりに。標準のMAMPセットアップをrootユーザーのdefaultsに変更せず、[db name]をご使用のdbに置き換え、コピーしてターミナルに貼り付け、ヒット入る。

/Applications/MAMP/Library/bin/mysql -u root -proot --skip-column-names [db name] -e 'SHOW TRIGGERS;' | cut -f1 | sed -E 's/(.*)/DROP TRIGGER IF EXISTS \1;/' | /Applications/MAMP/Library/bin/mysql -u root -proot [db name]

(ルートパスワードを更新した場合は、-pパスワード付き

0
webaholik

この目的のための単一コマンドの存在についてはわかりません。

しかし、ここで私はしばらく前にそれをやった方法です

  1. Dbでトリガーのリストを取得するスクリプトを作成します。
  2. dropTrigger.sqlファイルに連結リストを作成します
  3. DropTrigger.SQLファイルを実行する

トリガーのリストを取得するには、 SHOWトリガー または 情報スキーマのトリガーテーブル を使用できます。