2012-09-28 11 views

Odpowiedz

24

To jest stare pytanie, ale ponieważ wciąż pojawia się w moich poszukiwaniach, pomyślałem, że wstawię tutaj rozwiązanie. W moim przypadku potrzebowałem utworzyć pojedynczy plik, który miał pełny mysqldump, następnie upuszczałby wszystkie wyzwalacze, a następnie ponownie je wszystkie. Udało mi się to zrobić za pomocą poniższego polecenia, aby dołączyć oświadczenia DROP TRIGGER do mojego zrzutu przed dołączeniem zrzutu wyzwalaczy.

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 

Aby faktycznie spaść wszystkie wyzwalacze w tym samym poleceniu (jak wspomniano przez @Stephen Crosby w komentarzach), można po prostu rury to z powrotem do MySQL tak:

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

Uwielbiam to.Ale równie dobrze możesz po prostu przekierować go z powrotem do mysql zamiast do pliku: Zamiast ">> dump.sql" możesz po prostu użyć "| mysql -u [db user] -p [db password]" –

+0

To zależy bardzo dużo lub twój przypadek użycia. Dla mnie było to tworzenie pliku zrzutu z bazy danych niewolników, która służy do aktualizacji naszych baz danych deweloperów. To tylko część tego pliku zrzutu. Nie chciałbym tego uruchamiać w odniesieniu do naszego DB produkcyjnego, ale jest to część procesu aktualizacji lokalnej kopii DB produkcji dla rozwoju. Byłoby to jednak bardzo przydatne, gdybyś chciał uruchomić go w tej samej bazie danych. –

+0

Należy pamiętać, że użytkownicy BSD i OS X będą musieli używać 'sed -E' zamiast' sed -r'. – nofinator

0

Nie jestem pewien co do istnienia pojedynczego polecenia w tym celu.

Ale o to, jak to zrobiłem jakiś czas temu

  1. napisać skrypt do listy wyzwalaczy dostać w db.
  2. stworzyć listę Concated w dropTrigger.sql złożyć
  3. Run dropTrigger.SQL złożyć

Aby uzyskać listę wyzwalaczy można użyć SHOW trigger lub Triggers table in Information schema

-4

Szybka odpowiedź brzmi "nie".

Ale można zamknąć logikę w jednej procedurze przechowywanej: uzyskać wszystkie wyzwalacze i usunąć wszystkie z nich w pętli przy użyciu dynamicznego SQL.

Po to można wykonać: call delete_all_triggers_api(schema_name);

7

Niestety nie jest to możliwe w regularnych SQL lub procedury przechowywanej.

Rozwiązanie

Najprostszym rozwiązaniem upuścić wszystkie wyzwalacze mogą być skrypt 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 

wymaga pliki poświadczenia (.mysql.conf) tak:

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

Rozumowanie

Próba upuszczenia wyzwalacza z procedury składowanej zakończy się niepowodzeniem. Zgaduję, dzieje się tak dlatego zmienna może posiadać tylko ciąg i drop trigger wymaga nazwy wyzwalania (nie łańcuch zawierający nazwę wyzwalania):

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

Istnieją dwa wątki na ten temat na forach MySQL:

obaj dotrzeć do tego samego wniosku, że nawet przy użyciu zapisanego procedura nie pomoże.

+0

Nie można użyć przygotowanej instrukcji z procedurą składowaną, aby usunąć wyzwalacz? – jcoffland

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

skopiuj wyniki do schowka

przekonwertuj Trigger_name na DROP TRIGGER <trigger_name>; dla każdego spustu za pomocą znaczników^i S dla początku i końca wiersza z wyrażeń reg.

Uruchom jako skryptu SQL

0

MAC przy użyciu MAMP:

Jest kilka drobnych poprawek, które muszą być wykonane z przyjętym odpowiedź dla nas. Najpierw musimy skierować mysql do MAMP. Po drugie, sed -r nie działa na Macach, zamiast tego użyj sed -E. Zakładając standardową konfigurację MAMP, bez zmian domyślnych ustawień użytkownika root, po prostu zamień [nazwa db] na swoją bazę danych, a następnie skopiuj i wklej do Terminalu i naciśnij 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] 

(jeśli zostały zaktualizowane hasła administratora, po prostu zamienić się „root” po -p z hasłem

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

Kopiuj i wklej wygenerowany sql

+1

To zdecydowanie najlepsza odpowiedź. – user2831723

+0

Gdzie byłeś przyjacielem? (y) – NullPointer

4

nie jest możliwe, aby usunąć wszystkie wyzwalacze w bazie danych MySQL za pomocą jednej instrukcji SQL

Ale z następującym kodem SQL można zbudować listę wszystkich statuentów "DROP TRIGGER" ts (zastąpienie <your_schema> ze swoją nazwą schematu, np. imię i nazwisko w bazie):

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

Wynik poprzedniego zapytania będzie produkować coś takiego:

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

i można korzystać z tych SQL, aby ostatecznie usunąć wszystkie wyzwalacze.

Zmienna systemowa serwera group_concat_max_len jest maksymalną dozwoloną długością wyniku w bajtach dla funkcji GROUP_CONCAT(). Ponieważ domyślną wartością jest 1024, musimy ją zwiększyć, aby uniknąć obcinanego wyniku, jeśli mamy dużo wyzwalaczy. Po prostu użyłem wartości zmiennej systemowej serwera max_allowed_packet, ale zwykle jest w porządku każda duża liczba całkowita. Zobacz this other question.

0

W przypadku chcesz usunąć je za pomocą zapytania bez konieczności sqldump bazy danych do pliku:

select concat('drop trigger ', trigger_name, ';') from information_schema.triggers where trigger_schema = 'your_schema'; Następnie należy wyeksportować wyniki (znajdę do CSV najłatwiej) i uruchomić zapytań w tych wynikach.

Powiązane problemy