Jak debugować procedury składowane MySQL?

125

Mój obecny proces debugowania procedur składowanych jest bardzo prosty. Tworzę tabelę o nazwie „debug”, w której w trakcie działania wstawiam wartości zmiennych z procedury składowanej. To pozwala mi zobaczyć wartość dowolnej zmiennej w danym punkcie skryptu, ale czy istnieje lepszy sposób debugowania procedur składowanych MySQL?

Cory House
źródło
2
Czy są jakieś opcje GUI dla użytkowników innych niż Windows? Konieczność uruchomienia kopii systemu Windows tylko w celu debugowania procedur składowanych to trochę przeskok. A większość opcji wstawiania do tabeli nie działa, jeśli jesteś w transakcji, którą zamierzasz wycofać.
Code Abominator

Odpowiedzi:

44

Robię coś bardzo podobnego do ciebie.

Zwykle dołączam parametr DEBUG, który domyślnie ma wartość false i mogę ustawić go na true w czasie wykonywania. Następnie zawiń instrukcje debugowania w blok „If DEBUG”.

Używam również tabeli logowania do wielu moich zadań, aby móc przeglądać procesy i harmonogram. Mój kod debugowania również jest tam wyświetlany. Dołączam nazwę parametru wywołania, krótki opis, liczbę wierszy, na które ma to wpływ (w stosownych przypadkach), pole komentarza i znacznik czasu.

Dobre narzędzia do debugowania to jedna ze smutnych wad wszystkich platform SQL.

Bob Probst
źródło
3
Nie wszystkie platformy @Bob Probst, narzędzia do debugowania sybase są ciche i przyzwoite dzięki debugowaniu punktów przerwania dla wyzwalaczy i procedur składowanych
Anup,
69

Następującą debug_msgprocedurę można wywołać, aby po prostu wyprowadzić komunikat debugowania do konsoli:

DELIMITER $$

DROP PROCEDURE IF EXISTS `debug_msg`$$
DROP PROCEDURE IF EXISTS `test_procedure`$$

CREATE PROCEDURE debug_msg(enabled INTEGER, msg VARCHAR(255))
BEGIN
  IF enabled THEN
    select concat('** ', msg) AS '** DEBUG:';
  END IF;
END $$

CREATE PROCEDURE test_procedure(arg1 INTEGER, arg2 INTEGER)
BEGIN
  SET @enabled = TRUE;

  call debug_msg(@enabled, 'my first debug message');
  call debug_msg(@enabled, (select concat_ws('','arg1:', arg1)));
  call debug_msg(TRUE, 'This message always shows up');
  call debug_msg(FALSE, 'This message will never show up');
END $$

DELIMITER ;

Następnie uruchom test w następujący sposób:

CALL test_procedure(1,2)

Spowoduje to następujący wynik:

** DEBUG:
** my first debug message
** DEBUG:
** arg1:1
** DEBUG:
** This message always shows up
Brad Parks
źródło
8
Wydaje się, że to nie działa w przypadku FUNCTIONS i nie mam pojęcia, dlaczego. Zawsze zwraca „Kod błędu: 1415. Niedozwolone jest zwracanie zestawu wyników z funkcji”. Czy jest jakaś regres?
Patrick M
1
Funkcje @PatrickM nie mogą zwracać wierszy („wyników”), podczas gdy ta procedura debugowania opiera się na nich (komunikaty debugowania są zestawami wyników zwracanymi w wywołaniu procedury). W funkcjach możesz INSERT INTO my_log_table (message) VALUES (msg)pobrać wszystkie komunikaty debugowania dopiero po zakończeniu wywołań funkcji (tj. Wrócisz do procedury)
Xenos,
To podejście jest dobre, ale pisanie na konsolę nie jest efektywne w MySQL Workbench, tak jak w IDE. ponieważ każda instrukcja „select” otwiera nowe okienko wyników. Myślę, że lepiej jest utworzyć tymczasową tabelę dziennika do rejestrowania komunikatów o błędach z sygnaturą czasową i nazwą procedury
Mustafa Kemal Tuna
28

Tak, istnieje specjalistyczne narzędzie do tego typu rzeczy - MySQL Debugger .
wprowadź opis obrazu tutaj

Jerzy
źródło
5
tak bardzo chciałem go wypróbować. Niestety to totalny wrak. Otrzymuję komunikat o błędzie „funkcja coalesce nie istnieje” z mysql, w wyniku czego GUI rozgałęzia się nieprawidłowo przez kod SP (chociaż MySQL działa poprawnie). Nie wspominając o zmiennych lokalnych „DECLARE var DEFAULT value”. Po prostu pojawiają się jako NULL, kiedy wyraźnie nie są. Aha, a także „Niezadeklarowany identyfikator: 'FETCH_RADIUS_DISTSORT'”, gdzie była to skompilowana instrukcja. Niepolecane.
kellogs
4
To nie jest idealne, ale moja próba z tym była zupełnie innym doświadczeniem niż to opisane przez @kellogs powyżej. Narzędzie jest ładne i lekkie i wydaje się, że wykonuje dokładnie to, czego potrzeba, bez żadnych nadużyć. Było to dla mnie znacznie lepsze doświadczenie niż jakiekolwiek inne przetestowane narzędzia (tj. Visual Studio, Toad i dbForge Studio, z których wszystkie miały poważne wady - w porównaniu opisałyby je jako „totalny wrak”). Nie jestem pewien, czy dzieje się tak, ponieważ debugowana funkcja nie zawierała żadnej z wadliwych konstrukcji lub czy problemy zostały naprawione.
Steve Chambers
2
Okazało się również, że to narzędzie jest bardzo przydatne do debugowania moich procedur składowanych.
ralfe
22

Jak debugować procedurę składowaną MySQL.

Debuger dla biednych ludzi:

  1. Utwórz tabelę o nazwie logtable z dwiema kolumnami id INTi log VARCHAR(255).

  2. Ustaw automatyczne powiększanie kolumny identyfikatora.

  3. Użyj tej procedury:

    delimiter //
    DROP PROCEDURE `log_msg`//
    CREATE PROCEDURE `log_msg`(msg VARCHAR(255))
    BEGIN
        insert into logtable select 0, msg;
    END
  4. Umieść ten kod w dowolnym miejscu, w którym chcesz zarejestrować wiadomość w tabeli.

    call log_msg(concat('myvar is: ', myvar, ' and myvar2 is: ', myvar2));

To fajny, szybki i brudny mały rejestrator, aby dowiedzieć się, co się dzieje.

Eric Leschinski
źródło
21

Istnieją narzędzia GUI do debugowania procedur / funkcji składowanych i skryptów w MySQL. Przyzwoite narzędzie, które dbForge Studio dla MySQL, ma bogatą funkcjonalność i stabilność.

Josef Miran
źródło
Trudno jest znaleźć platformy, na których działa to narzędzie do debugowania. Wydaje się, że działa w systemie Windows. Coś jeszcze?
Guy,
11

Debugger dla mysql był dobry, ale nie jest darmowy. Oto, czego teraz używam:

DELIMITER GO$

DROP PROCEDURE IF EXISTS resetLog

GO$

Create Procedure resetLog() 
BEGIN   
    create table if not exists log (ts timestamp default current_timestamp, msg varchar(2048)) engine = myisam; 
    truncate table log;
END; 

GO$

DROP PROCEDURE IF EXISTS doLog 

GO$

Create Procedure doLog(in logMsg nvarchar(2048))
BEGIN  
  insert into log (msg) values(logMsg);
END;

GO$

Użycie w procedurze składowanej:

call dolog(concat_ws(': ','@simple_term_taxonomy_id',  @simple_term_taxonomy_id));

użycie procedury składowanej:

call resetLog ();
call stored_proc();
select * from log;
Tone Škoda
źródło
8

Przedstawiono tutaj inny sposób

http://gilfster.blogspot.co.at/2006/03/debugging-stored-procedures-in-mysql.html

z niestandardowymi procedurami debugowania mySql i tabelami logowania.

Możesz także po prostu umieścić w kodzie prosty wybór i sprawdzić, czy jest wykonywany.

SELECT 'Message Text' AS `Title`; 

Wpadłem na ten pomysł

http://forums.mysql.com/read.php?99,78155,78225#msg-78225

Ktoś również stworzył szablon dla niestandardowych procedur debugowania na GitHub.

Spójrz tutaj

http://www.bluegecko.net/mysql/debugging-stored-procedures/ https://github.com/CaptTofu/Stored-procedure-debugging-routines

Wspomniano tutaj

Jak złapać wyjątek w wyzwalaczach i przechowywać procedury dla mysql?

Jeremy S.
źródło
7

Po prostu umieszczam instrukcje select w kluczowych obszarach procedury składowanej, aby sprawdzić aktualny stan zestawów danych, a następnie komentuję je (--select ...) lub usuwam je przed produkcją.

Ash Machine
źródło
7

Spóźniłem się na imprezę, ale przyniosłem więcej piwa:

http://ocelot.ca/blog/blog/2015/03/02/the-ocelotgui-debugger/ i https://github.com/ocelot-inc/ocelotgui

Próbowałem i wydaje się całkiem stabilny, obsługując inspekcję punktów przerwania i zmiennej.

Nie jest to kompletny zestaw (tylko 4,1 Mb), ale bardzo mi pomógł!

Jak to działa: integruje się z Twoim klientem mysql (używam Ubuntu 14.04), a po wykonaniu:

$install
$setup yourFunctionName

Instaluje nową bazę danych na serwerze, która kontroluje proces debugowania. Więc:

$debug yourFunctionName('yourParameter')

da Ci szansę na przejrzenie kodu krok po kroku i „odświeżenie” zmiennych, dzięki czemu będziesz mógł lepiej zobaczyć, co dzieje się w kodzie.

Ważna wskazówka: podczas debugowania może zmienisz (ponownie utwórz procedurę). Po ponownym utworzeniu wykonaj: $ exit i $ setup przed nowym $ debug

Jest to alternatywa dla metod „insert” i „log”. Twój kod pozostaje wolny od dodatkowych instrukcji „debugowania”.

Zrzut ekranu:

ocelot breakpoint stepping

Marcelo Amorim
źródło
6

MySQL Connector / Net 6.6 ma funkcję debugowania procedur składowanych i funkcji

Instalowanie debugera

Aby włączyć debuger procedury składowanej:

  • Dla Connector / Net 6.6: zainstaluj Connector / Net 6.6 i wybierz opcję Complete.
  • W przypadku oprogramowania Connector / Net 6.7 i nowszych: zainstaluj produkt MySQL dla programu Visual Studio, do którego należy debugger procedur składowanych.

Uruchamianie debugera

Aby uruchomić debugera, wykonaj następujące kroki:

  • Wybierz połączenie w programie Visual Studio Server Explorer.
  • Rozwiń folder Procedury składowane. Bezpośrednio debugować można tylko procedury składowane. Aby debugować funkcję zdefiniowaną przez użytkownika, utwórz plik
    procedurę , która wywołuje funkcję.
  • Kliknij węzeł procedury składowanej, a następnie kliknij prawym przyciskiem myszy iz menu kontekstowego wybierz opcję Debuguj procedurę.
Rahul Tripathi
źródło
5

MySql Connector / NET zawiera również debugger procedur składowanych zintegrowany z Visual Studio od wersji 6.6. Instalator i źródło można pobrać tutaj: http://dev.mysql.com/downloads/connector/net/

Część dokumentacji / zrzutów ekranu: https://dev.mysql.com/doc/visual-studio/en/visual-studio-debugger.html

Możesz śledzić ogłoszenia tutaj: http://forums.mysql.com/read.php?38,561817,561817#msg-561817

AKTUALIZACJA: MySql for Visual Studio został podzielony z Connector / NET na osobny produkt, możesz go wybrać (w tym debugger) stąd https://dev.mysql.com/downloads/windows/visualstudio/1.2.html (nadal darmowe i otwarte).

ZRZECZENIE SIĘ: Byłem programistą, który jest autorem mechanizmu debugera procedur składowanych dla produktu MySQL dla programu Visual Studio.

Fernando Gonzalez Sanchez
źródło
Podczas korzystania z MySQL i Connector .NET występuje problem z parametrami połączenia z wieloma hostami. Wyjaśniłem tutaj sprawę ... Zastanawiałem się, czy ktoś się tym zajmie? To spowodowało spory problem dla wielu z nas programistów .Net, którzy używają MySQL ...
Hooman Bahreini,
1
Przykro mi to słyszeć, nie pracuję już w Oracle i nie mam dużo wolnego czasu, sugeruję skontaktowanie się z obsługą MySQL.
Fernando Gonzalez Sanchez
4

Pierwszy i stabilny debugger dla MySQL znajduje się w dbForge Studio dla MySQL

Zoitc2014
źródło
3

Użyłem dwóch różnych narzędzi do debugowania procedur i funkcji:

  1. dbForge - wiele funkcjonalnych GUI mysql.
  2. MyDebugger - wyspecjalizowane narzędzie do debugowania ... poręczne narzędzie do debugowania. głosuj http://tinyurl.com/voteimg
GeoGo
źródło
3

Zmienna zdefiniowana przez użytkownika MySQL (udostępniona w sesji) może być użyta jako dane wyjściowe logowania:

DELIMITER ;;
CREATE PROCEDURE Foo(tableName VARCHAR(128))
BEGIN
  SET @stmt = CONCAT('SELECT * FROM ', tableName);
  PREPARE pStmt FROM @stmt;
  EXECUTE pStmt;
  DEALLOCATE PREPARE pStmt;
  -- uncomment after debugging to cleanup
  -- SET @stmt = null;
END;;
DELIMITER ;
call Foo('foo');
select @stmt;

wyświetli:

SELECT * FROM foo
clarkttfu
źródło
1

Toad mysql. Dostępna jest darmowa wersja http://www.quest.com/toad-for-mysql/

Joyce
źródło
1
Używam Ropucha od lat, ale nie wiedziałem, że ma on jakieś specjalne funkcje do debugowania sproców. Czy możesz wyjaśnić, jak używasz do tego Ropuchy?
Cory House
Spojrzałem na Toad 6.3 dla mysql, wygląda na to, że jest tam funkcja debugowania z punktami przerwania i wszystkim. Czy masz na myśli, że funkcja debugowania nie działa? A może Twoja wersja jest starsza i nie zawiera funkcji debugowania?
Joyce
1

Odpowiedź odpowiadająca temu autorstwa @Brad Parks Nie jestem pewien co do wersji MySQL, ale moja to 5.6, stąd trochę poprawek:

Utworzyłem funkcję, debug_msgktóra jest funkcją (nie procedurą) i zwraca tekst (bez limitu znaków), a następnie wywołałem funkcję jako SELECT debug_msg(params) AS my_res_set, kod jak poniżej:

CREATE DEFINER=`root`@`localhost` FUNCTION `debug_msg`(`enabled` INT(11), `msg` TEXT) RETURNS text CHARSET latin1
    READS SQL DATA
BEGIN
    IF enabled=1 THEN
    return concat('** DEBUG:', "** ", msg);
    END IF;
END

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_func_call`(
 IN RegionID VARCHAR(20),
 IN RepCurrency INT(11),
 IN MGID INT(11),
 IN VNC VARCHAR(255)
)
BEGIN
    SET @enabled = TRUE;
    SET @mainQuery = "SELECT * FROM Users u";
    SELECT `debug_msg`(@enabled, @mainQuery) AS `debug_msg1`;
    SET @lastQuery = CONCAT(@mainQuery, " WHERE u.age>30);
    SELECT `debug_msg`(@enabled, @lastQuery) AS `debug_msg2`;
END $$
DELIMITER
aniruddha
źródło