2012-09-28 47 views
24

Tôi có một DB mà tôi đã nhân bản và bây giờ tất cả các trình kích hoạt ghi nhật ký trỏ tới các bảng ghi trong lược đồ gốc. Tôi cần phải xóa tất cả chúng trong một lần (có vài chục) để tôi có thể tạo lại chúng. Làm thế nào điều này có thể được thực hiện với một lệnh?Làm cách nào để xóa tất cả các trình kích hoạt trong cơ sở dữ liệu MySQL bằng một câu lệnh SQL?

Trả lời

24

Đây là một câu hỏi cũ, nhưng vì đó là câu hỏi tiếp tục xuất hiện trong các tìm kiếm của tôi, tôi nghĩ tôi nên đăng một giải pháp ở đây. Trong trường hợp của tôi, tôi cần tạo một tệp duy nhất có đầy đủ mysqldump, sau đó sẽ thả bất kỳ trình kích hoạt nào và sau đó thêm lại tất cả. Tôi đã có thể làm điều đó bằng cách sử dụng lệnh sau để chắp thêm các câu lệnh DROP TRIGGER vào kết xuất của tôi trước khi gắn thêm kết xuất của trình kích hoạt.

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 

Để thực sự thả tất cả các trigger trong cùng một lệnh (như đã đề cập bởi @Stephen Crosby trong các ý kiến), bạn có thể chỉ đường ống này trở lại vào MySQL như vậy:

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] 
+2

Tôi thích nó.Nhưng bạn cũng có thể chỉ cần đặt nó trở lại vào mysql chứ không phải là tệp: Thay vì ">> dump.sql", bạn chỉ có thể sử dụng "| mysql -u [db user] -p [mật khẩu db]" –

+0

Điều đó phụ thuộc rất nhiều hoặc trường hợp sử dụng của bạn. Đối với tôi, nó đã tạo một tệp kết xuất khỏi cơ sở dữ liệu nô lệ được sử dụng để cập nhật cơ sở dữ liệu dev của chúng tôi. Đây chỉ là một phần của tệp kết xuất đó. Tôi sẽ không muốn điều này chống lại DB sản xuất của chúng tôi, nhưng nó là một phần của quá trình cập nhật một bản sao địa phương của DB sản xuất để phát triển. Điều đó sẽ rất tiện dụng mặc dù nếu bạn muốn chạy nó trên cùng một cơ sở dữ liệu. –

+0

Lưu ý rằng người dùng BSD và OS X sẽ cần phải sử dụng 'sed -E' thay vì' sed -r'. – nofinator

0

Không chắc chắn về sự tồn tại của lệnh đơn cho mục đích này.

Nhưng đây là cách tôi đã làm nó một thời gian trở lại

  1. Viết kịch bản để có được danh sách các trigger trong db.
  2. tạo Concated danh sách trong dropTrigger.sql nộp nộp
  3. Run dropTrigger.SQL

Để có được Danh sách các trigger bạn có thể sử dụng SHOW trigger hoặc Triggers table in Information schema

-4

Câu trả lời nhanh chóng là "không".

Nhưng bạn có thể đóng gói logic trong một thủ tục được lưu trữ: nhận tất cả các trình kích hoạt và xóa tất cả chúng trong vòng lặp bằng cách sử dụng SQL động.

Sau là bạn có thể thực hiện: call delete_all_triggers_api(schema_name);

7

Đáng tiếc là điều này không thể trong một câu lệnh SQL thường xuyên hoặc một thủ tục lưu trữ.

Giải pháp

Giải pháp đơn giản nhất để thả tất cả các trigger có thể là một kịch bản 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 

Điều này đòi hỏi nộp chứng chỉ (.mysql.conf) như sau:

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

Lý do

Cố gắng để thả một kích hoạt từ một thủ tục lưu trữ sẽ thất bại. Tôi đoán điều này xảy ra bởi vì một biến chỉ có thể tổ chức một chuỗi và drop trigger đòi hỏi một tên cò (không phải là một chuỗi chứa một tên cò):

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(); 

Có hai chủ đề về vấn đề này trên các diễn đàn MySQL:

cả hai đều đạt được cùng một kết luận rằng ngay cả sử dụng một lưu trữ thủ thuật sẽ không giúp ích gì.

+0

Bạn không thể sử dụng câu lệnh đã chuẩn bị với quy trình được lưu trữ để thả trình kích hoạt? – jcoffland

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

sao chép kết quả vào clipboard

chuyển đổi Trigger_name thành DROP TRIGGER <trigger_name>; cho mỗi trình kích hoạt sử dụng thẻ^và S để bắt đầu và kết thúc bằng reg.expressions

chạy như kịch bản sql

0

MAC sử dụng MAMP:

Có một số thay đổi nhỏ mà cần phải được thực hiện để trả lời chấp nhận cho chúng tôi. Trước tiên, chúng ta cần nhắm mục tiêu mysql trong MAMP. Thứ hai, sed -r không hoạt động đối với Mac, thay vào đó hãy sử dụng sed -E. Giả sử thiết lập MAMP chuẩn, không có thay đổi đối với giá trị mặc định của người dùng gốc, chỉ cần thay thế [tên db] bằng db của bạn, sau đó sao chép và dán vào Thiết bị đầu cuối và nhấn enter.

/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] 

(nếu bạn đã cập nhật mật khẩu gốc của bạn, chỉ cần trao đổi trên "gốc" sau -p với mật khẩu của bạn

17
SELECT Concat('DROP TRIGGER ', Trigger_Name, ';') FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = 'your_schema'; 

Sao chép và dán sql tạo

+1

Đây là câu trả lời hay nhất – user2831723

+0

Bạn đã ở đâu với bạn? (y) – NullPointer

4

Nó không thể xóa tất cả các trình kích hoạt trong cơ sở dữ liệu MySQL sử dụng một câu lệnh SQL

Nhưng với mã SQL sau đây bạn có thể xây dựng danh sách tất cả các statemen 'DROP TRIGGER' ts (thay thế <your_schema> bằng tên lược đồ của bạn, ví dụ: tên cơ sở dữ liệu của bạn):

-- 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'; 

Kết quả của truy vấn trước đó sẽ tạo ra một cái gì đó như:

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

Và bạn có thể sử dụng các câu lệnh SQL để cuối cùng xóa tất cả các kích hoạt.

Biến hệ thống máy chủ group_concat_max_len là độ dài kết quả tối đa cho phép tính theo byte cho hàm GROUP_CONCAT(). Bởi vì mặc định là 1024, chúng ta cần tăng nó để tránh một kết quả bị cắt bớt nếu chúng ta có nhiều trigger. Tôi chỉ sử dụng giá trị của biến hệ thống máy chủ max_allowed_packet, nhưng thường là tốt bất kỳ số nguyên lớn nào. Xem this other question.

0

Trong trường hợp bạn muốn thả chúng sử dụng một truy vấn mà không cần phải sqldump cơ sở dữ liệu vào một tập tin:

select concat('drop trigger ', trigger_name, ';') from information_schema.triggers where trigger_schema = 'your_schema'; Sau đó bạn sẽ cần phải xuất kết quả (Tôi tìm đến CSV là dễ nhất) và chạy truy vấn trong các kết quả đó.

Các vấn đề liên quan