Wie debuggen Sie gespeicherte MySQL-Prozeduren?

125

Mein aktueller Prozess zum Debuggen gespeicherter Prozeduren ist sehr einfach. Ich erstelle eine Tabelle namens "debug", in die ich während der Ausführung Variablenwerte aus der gespeicherten Prozedur einfüge. Auf diese Weise kann ich den Wert einer Variablen an einem bestimmten Punkt im Skript anzeigen. Gibt es jedoch eine bessere Möglichkeit, gespeicherte MySQL-Prozeduren zu debuggen?

Cory House
quelle
2
Gibt es GUI-Optionen für Nicht-Windows-Benutzer? Eine Kopie von Windows ausführen zu müssen, um gespeicherte Prozeduren zu debuggen, ist ein kleiner Sprung. Die meisten Optionen zum Einfügen von Tabellen schlagen fehl, wenn Sie sich in einer Transaktion befinden, die Sie zurücksetzen möchten.
Code Abominator

Antworten:

44

Ich mache dir etwas sehr ähnliches.

Normalerweise füge ich einen DEBUG-Parameter hinzu, der standardmäßig false ist, und ich kann zur Laufzeit auf true setzen. Wickeln Sie dann die Debug-Anweisungen in einen "If DEBUG" -Block.

Ich verwende auch eine Protokollierungstabelle mit vielen meiner Jobs, damit ich Prozesse und das Timing überprüfen kann. Dort wird auch mein Debug-Code ausgegeben. Ich füge den Namen des aufrufenden Parameters, eine kurze Beschreibung, die Anzahl der betroffenen Zeilen (falls zutreffend), ein Kommentarfeld und einen Zeitstempel hinzu.

Gute Debugging-Tools sind einer der traurigen Fehler aller SQL-Plattformen.

Bob Probst
quelle
3
Nicht alle Plattformen @Bob Probst, Sybase-Debugging-Tools sind mit Breakpoint-Debugging für Trigger und gespeicherte Prozeduren recht anständig
Anup
69

Die folgende debug_msgProzedur kann aufgerufen werden, um einfach eine Debug-Nachricht an die Konsole auszugeben:

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 ;

Führen Sie den Test dann folgendermaßen aus:

CALL test_procedure(1,2)

Dies führt zu folgender Ausgabe:

** DEBUG:
** my first debug message
** DEBUG:
** arg1:1
** DEBUG:
** This message always shows up
Brad Parks
quelle
8
Dies scheint für FUNCTIONS nicht zu funktionieren und ich habe keine Ahnung warum. Es wird immer "Fehlercode: 1415" angezeigt. Es ist nicht zulässig, eine Ergebnismenge von einer Funktion zurückzugeben. Gibt es einen Rückgriff?
Patrick M
1
@PatrickM-Funktionen können keine Zeilen ("Ergebnis") zurückgeben, während diese Debug-Prozedur darauf beruht (die Debug-Meldungen sind Ergebnismengen, die im Prozeduraufruf zurückgegeben werden). In Funktionen können Sie möglicherweise erst INSERT INTO my_log_table (message) VALUES (msg)alle Debug-Meldungen abrufen, wenn die Funktionsaufrufe beendet sind (dh Sie sind wieder in der Prozedur)
Xenos
Dieser Ansatz ist gut, aber das Schreiben in die Konsole ist auf MySQL Workbench wie IDEs nicht effektiv. weil jede "select" -Anweisung einen neuen Ergebnisbereich öffnet. Ich denke, es ist besser, eine temporäre Protokolltabelle zu erstellen, um Fehlermeldungen mit Zeitstempel und Prozedurname zu protokollieren
mustafa kemal tuna
28

Ja, es gibt spezielle Tools für diese Art von Dingen - MySQL Debugger .
Geben Sie hier die Bildbeschreibung ein

George
quelle
5
Ich war so gespannt darauf, es auszuprobieren. Leider ist es ein totales Wrack. Ich erhalte die Fehlermeldung "Funktionskoaleszenz existiert nicht", angeblich von MySQL. Infolgedessen verzweigt die GUI falsch über SP-Code (obwohl MySQL sie korrekt ausführt). Ganz zu schweigen von den lokalen Variablen "DECLARE var DEFAULT value". Sie werden nur als NULL angezeigt, wenn dies eindeutig nicht der Fall ist. Oh, und auch "Nicht deklarierter Bezeichner: 'FETCH_RADIUS_DISTSORT'", wo dies eine kompilierte Anweisung war. Nicht empfohlen.
Kellogs
4
Es ist nicht perfekt, aber mein Versuch damit war eine ganz andere Erfahrung als die, über die @kellogs oben berichtet hat. Das Werkzeug ist schön und leicht und scheint genau die Arbeit zu erledigen, die benötigt wird, ohne aufzublähen. Es war eine weitaus bessere Erfahrung für mich als jedes andere getestete Tool (dh Visual Studio, Toad und dbForge Studio, die alle große Mängel aufwiesen - würde all dies im Vergleich als "totales Wrack" bezeichnen). Ich bin mir nicht sicher, ob dies daran liegt, dass die zu debuggende Funktion keines der fehlerhaften Konstrukte enthielt oder ob die Probleme behoben wurden.
Steve Chambers
2
Ich fand dieses Tool auch sehr nützlich zum Debuggen meiner gespeicherten Prozeduren.
Ralfe
22

So debuggen Sie eine gespeicherte MySQL-Prozedur.

Debugger des armen Mannes:

  1. Erstellen Sie eine Tabelle namens logtable mit zwei Spalten. id INT und log VARCHAR(255).

  2. Führen Sie eine automatische Inkrementierung der ID-Spalte durch.

  3. Verwenden Sie dieses Verfahren:

    delimiter //
    DROP PROCEDURE `log_msg`//
    CREATE PROCEDURE `log_msg`(msg VARCHAR(255))
    BEGIN
        insert into logtable select 0, msg;
    END
  4. Platzieren Sie diesen Code an einer beliebigen Stelle, an der Sie eine Nachricht in der Tabelle protokollieren möchten.

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

Es ist ein netter schneller und schmutziger kleiner Logger, um herauszufinden, was los ist.

Eric Leschinski
quelle
21

Es gibt GUI-Tools zum Debuggen gespeicherter Prozeduren / Funktionen und Skripte in MySQL. Ein anständiges Tool, das dbForge Studio für MySQL bietet und über umfangreiche Funktionen und Stabilität verfügt.

Josef Miran
quelle
Es ist schwierig zu finden, auf welchen Plattformen das Debug-Tool ausgeführt wird. Scheint unter Windows zu laufen. Noch etwas?
Guy
10

Der Debugger für MySQL war gut, aber nicht kostenlos. Das benutze ich jetzt:

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$

Verwendung in gespeicherten Prozeduren:

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

Verwendung der gespeicherten Prozedur:

call resetLog ();
call stored_proc();
select * from log;
Ton Škoda
quelle
8

Ein anderer Weg wird hier vorgestellt

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

mit benutzerdefinierten Debug-MySQL-Prozeduren und Protokollierungstabellen.

Sie können auch einfach eine Auswahl in Ihren Code einfügen und prüfen, ob er ausgeführt wird.

SELECT 'Message Text' AS `Title`; 

Ich habe diese Idee von

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

Außerdem hat jemand eine Vorlage für benutzerdefinierte Debug-Prozeduren auf GitHub erstellt.

Siehe hier

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

Wurde hier erwähnt

Wie kann man Ausnahmen in Triggern und Speicherprozeduren für MySQL abfangen?

Jeremy S.
quelle
7

Ich platziere einfach select-Anweisungen in Schlüsselbereichen der gespeicherten Prozedur, um den aktuellen Status von Datensätzen zu überprüfen, und kommentiere sie dann aus (--select ...) oder entferne sie vor der Produktion.

Aschemaschine
quelle
7

Ich bin zu spät zur Party, habe aber noch mehr Bier mitgebracht:

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

Ich habe es versucht, und es scheint ziemlich stabil zu sein, Breakpoints und Variable Inspection zu unterstützen.

Es ist keine komplette Suite (nur 4,1 MB), hat mir aber sehr geholfen!

So funktioniert es: Es lässt sich in Ihren MySQL-Client integrieren (ich verwende Ubuntu 14.04) und nach der Ausführung:

$install
$setup yourFunctionName

Auf Ihrem Server wird eine neue Datenbank installiert, die den Debugging-Prozess steuert. So:

$debug yourFunctionName('yourParameter')

Sie haben die Möglichkeit, Schritt für Schritt durch Ihren Code zu gehen und Ihre Variablen zu "aktualisieren". So können Sie besser sehen, was in Ihrem Code vor sich geht.

Wichtiger Tipp: Während des Debuggens werden Sie möglicherweise Änderungen vornehmen (die Prozedur neu erstellen). Führen Sie nach einer Neuerstellung Folgendes aus: $ exit und $ setup vor einem neuen $ debug

Dies ist eine Alternative zu den Methoden "Einfügen" und "Protokollieren". Ihr Code bleibt frei von zusätzlichen "Debug" -Anweisungen.

Bildschirmfoto:

Ocelot Breakpoint Stepping

Marcelo Amorim
quelle
6

MySQL Connector / Net 6.6 bietet eine Funktion zum Debuggen gespeicherter Prozeduren und Funktionen

Debugger installieren

So aktivieren Sie den Debugger für gespeicherte Prozeduren:

  • Für Connector / Net 6.6: Installieren Sie Connector / Net 6.6 und wählen Sie die Option Vollständig.
  • Für Connector / Net 6.7 und höher: Installieren Sie das Produkt MySQL für Visual Studio, zu dem der Debugger für gespeicherte Prozeduren gehört.

Starten des Debuggers

Gehen Sie folgendermaßen vor, um den Debugger zu starten:

  • Wählen Sie im Visual Studio Server Explorer eine Verbindung aus.
  • Erweitern Sie den Ordner Gespeicherte Prozeduren. Nur gespeicherte Prozeduren können direkt debuggt werden. Erstellen Sie eine gespeicherte Funktion, um eine benutzerdefinierte Funktion zu debuggen
    Prozedur, die die Funktion aufruft.
  • Klicken Sie auf einen Knoten für gespeicherte Prozeduren, klicken Sie mit der rechten Maustaste und wählen Sie im Kontextmenü die Option Debug-Routine.
Rahul Tripathi
quelle
5

MySql Connector / NET enthält auch einen Debugger für gespeicherte Prozeduren, der ab Version 6.6 in Visual Studio integriert ist. Das Installationsprogramm und die Quelle finden Sie hier: http://dev.mysql.com/downloads/connector/net/

Einige Dokumentationen / Screenshots: https://dev.mysql.com/doc/visual-studio/en/visual-studio-debugger.html

Sie können den Ankündigungen hier folgen: http://forums.mysql.com/read.php?38,561817,561817#msg-561817

UPDATE: MySql für Visual Studio wurde von Connector / NET in ein separates Produkt aufgeteilt. Sie können es (einschließlich des Debuggers) hier auswählen: https://dev.mysql.com/downloads/windows/visualstudio/1.2.html (noch) kostenlos & Open Source).

HAFTUNGSAUSSCHLUSS: Ich war der Entwickler, der die Debugger-Engine für gespeicherte Prozeduren für das Produkt MySQL for Visual Studio erstellt hat.

Fernando Gonzalez Sanchez
quelle
Bei Verwendung von MySQL und Connector .NET tritt ein Problem mit der Verbindungszeichenfolge für mehrere Hosts auf. Ich habe das Problem hier erklärt . Ich habe mich gefragt, ob sich jemand darum kümmern wird. Dies hat für viele von uns ein ziemliches Problem verursacht.
Net-
1
Es tut mir leid das zu hören, ich arbeite nicht mehr bei Oracle und habe nicht viel Freizeit. Ich schlage vor, mich mit dem MySQL-Support in Verbindung zu setzen.
Fernando Gonzalez Sanchez
4

Der erste und stabile Debugger für MySQL befindet sich in dbForge Studio für MySQL

Zoitc2014
quelle
3

Ich hatte zwei verschiedene Tools zum Debuggen von Prozeduren und Funktionen verwendet:

  1. dbForge - viele funktionale MySQL-GUI.
  2. MyDebugger - spezialisiertes Tool zum Debuggen ... praktisches Tool zum Debuggen. Abstimmung http://tinyurl.com/voteimg
GeoGo
quelle
3

Die benutzerdefinierte MySQL-Variable (in der Sitzung freigegeben) kann als Protokollierungsausgabe verwendet werden:

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;

wird ausgegeben:

SELECT * FROM foo
clarkttfu
quelle
1

Kröte MySQL. Es gibt eine Freeware-Version http://www.quest.com/toad-for-mysql/

Joyce
quelle
1
Ich habe Toad jahrelang verwendet, war mir aber nicht bewusst, dass es spezielle Funktionen zum Debuggen von Sprocs gibt. Können Sie klarstellen, wie Sie Toad dazu verwenden?
Cory House
In Toad 6.3 für MySQL wurde gerade eine Debug-Funktion mit Haltepunkten und allem angezeigt. Meinen Sie damit, dass die Debug-Funktion nicht funktioniert? Oder ist Ihre Version älter und enthält keine Debug-Funktion?
Joyce
1

Antwort auf entsprechende diese durch @Brad Parks Nicht sicher über die MySQL - Version, aber ich war 5,6, also ein wenig Zwicken Werke:

Ich habe eine Funktion erstellt, debug_msgdie Funktion (keine Prozedur) ist und Text zurückgibt (keine Zeichenbeschränkung), und dann die Funktion als SELECT debug_msg(params) AS aufgerufen my_res_set, Code wie folgt :

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
quelle