Come si esegue il debug delle stored procedure MySQL?


125

Il mio attuale processo per il debug delle stored procedure è molto semplice. Creo una tabella chiamata "debug" dove inserisco i valori delle variabili dalla stored procedure mentre viene eseguita. Questo mi consente di vedere il valore di qualsiasi variabile in un dato punto dello script, ma esiste un modo migliore per eseguire il debug delle stored procedure MySQL?


2
Esistono opzioni GUI per utenti non Windows? Dover eseguire una copia di Windows solo per eseguire il debug delle stored procedure è un po 'un salto. E la maggior parte delle opzioni di inserimento della tabella non riesce se ti trovi in ​​una transazione che stai per eseguire il rollback.
Abominatore di codice

Risposte:


44

Faccio qualcosa di molto simile a te.

Di solito includerò un parametro DEBUG che di default è false e posso impostare su true in fase di esecuzione. Quindi racchiudi le istruzioni di debug in un blocco "If DEBUG".

Uso anche una tabella di registrazione con molti dei miei lavori in modo da poter rivedere i processi e le tempistiche. Anche il mio codice di debug viene emesso lì. Includo il nome del parametro chiamante, una breve descrizione, i conteggi delle righe interessati (se appropriato), un campo commenti e un timestamp.

I buoni strumenti di debug sono uno dei tristi fallimenti di tutte le piattaforme SQL.


3
Non tutte le piattaforme @Bob Probst, gli strumenti di debug di sybase sono abbastanza decenti con debug del punto di interruzione per trigger e stored procedure
Anup

69

La seguente debug_msgprocedura può essere chiamata per inviare semplicemente un messaggio di debug alla console:

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 ;

Quindi esegui il test in questo modo:

CALL test_procedure(1,2)

Il risultato sarà il seguente output:

** DEBUG:
** my first debug message
** DEBUG:
** arg1:1
** DEBUG:
** This message always shows up

8
Questo non sembra funzionare per FUNCTIONS e non ho idea del perché. Fornisce sempre "Codice errore: 1415. Non è consentito restituire un set di risultati da una funzione". C'è qualche ricorso?
Patrick M

1
Le funzioni @PatrickM non possono restituire righe ("risultato") mentre questa procedura di debug si basa su di essa (i messaggi di debug sono set di risultati restituiti nella chiamata di procedura). Nelle funzioni, puoi solo INSERT INTO my_log_table (message) VALUES (msg)e forse recuperare tutti i messaggi di debug una volta che le chiamate di funzione sono finite (ad esempio: sei tornato nella procedura)
Xenos

Questo approccio è buono ma scrivere su console non è efficace su MySQL Workbench come gli IDE. perché ogni istruzione "select" apre un nuovo riquadro dei risultati. Penso che sia meglio creare una tabella di registro temporanea per registrare i messaggi di errore con il timestamp e il nome della procedura
mustafa kemal tuna

28

Sì, esiste uno strumento specializzato per questo genere di cose: MySQL Debugger .
inserisci qui la descrizione dell'immagine


5
ero così ansioso di provarlo. Purtroppo è un relitto totale. Ricevo il messaggio di errore "function coalesce non esiste" suppsedly da mysql, di conseguenza la GUI si dirama in modo errato tramite il codice SP (sebbene MySQL lo esegua correttamente). Per non parlare delle variabili locali "DECLARE var DEFAULT value". Si presentano semplicemente come NULL quando chiaramente non lo sono. Oh, e anche "Identificatore non dichiarato: 'FETCH_RADIUS_DISTSORT'" dove quella era un'istruzione compilata. Non consigliato.
kellogs

4
Non è perfetto ma la mia prova con questo è stata un'esperienza molto diversa da quella riportata da @kellogs sopra. Lo strumento è bello e leggero e sembra fare proprio il lavoro necessario senza gonfiare. È stata un'esperienza di gran lunga migliore per me rispetto a qualsiasi altro strumento provato (ad esempio Visual Studio, Toad e dbForge Studio, che presentavano tutti grandi difetti - descriverebbero tutti questi come un "relitto totale" in confronto). Non sono sicuro che ciò sia dovuto al fatto che la funzione in fase di debug non includeva nessuno dei costrutti difettosi o se i problemi sono stati risolti.
Steve Chambers il

2
Ho anche trovato questo strumento molto utile per il debug delle mie stored procedure.
ralfe

22

Come eseguire il debug di una stored procedure MySQL.

Debugger dei poveri:

  1. Creare una tabella denominata logtable con due colonne id INTe log VARCHAR(255).

  2. Rende la colonna id autoincrement.

  3. Usa questa procedura:

    delimiter //
    DROP PROCEDURE `log_msg`//
    CREATE PROCEDURE `log_msg`(msg VARCHAR(255))
    BEGIN
        insert into logtable select 0, msg;
    END
  4. Metti questo codice ovunque tu voglia registrare un messaggio nella tabella.

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

È un bel logger veloce e sporco per capire cosa sta succedendo.



10

Il debugger per mysql era buono ma non è gratuito. Questo è quello che uso ora:

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$

Utilizzo nella stored procedure:

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

utilizzo della stored procedure:

call resetLog ();
call stored_proc();
select * from log;

8

Un altro modo è presentato qui

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

con procedure personalizzate di debug mySql e tabelle di registrazione.

Puoi anche inserire una semplice selezione nel tuo codice e vedere se viene eseguito.

SELECT 'Message Text' AS `Title`; 

Ho avuto questa idea da

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

Inoltre qualcuno ha creato un modello per procedure di debug personalizzate su GitHub.

Vedere qui

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

È stato menzionato qui

Come rilevare eventuali eccezioni nei trigger e memorizzare le procedure per mysql?


7

Posiziono semplicemente le istruzioni select nelle aree chiave della procedura memorizzata per controllare lo stato corrente dei set di dati, quindi le commento (--select ...) o le rimuovo prima della produzione.


7

Sono in ritardo alla festa, ma ho portato altra birra:

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

Ho provato, e sembra abbastanza stabile, supportando Breakpoints e Variable Inspection.

Non è una suite completa (solo 4,1 Mb) ma mi ha aiutato molto!

Come funziona: si integra con il tuo client mysql (sto usando Ubuntu 14.04) e dopo aver eseguito:

$install
$setup yourFunctionName

Installa un nuovo database sul tuo server, che controlla il processo di debug. Così:

$debug yourFunctionName('yourParameter')

ti darà la possibilità di seguire passo dopo passo il codice e "rinfrescando" le tue variabili potrai vedere meglio cosa sta succedendo all'interno del tuo codice.

Suggerimento importante: durante il debug, forse cambierai (ricrea la procedura). Dopo una ricreazione, eseguire: $ exit e $ setup prima di un nuovo $ debug

Questa è un'alternativa ai metodi "insert" e "log". Il codice rimane privo di ulteriori istruzioni di "debug".

Immagine dello schermo:

passo di interruzione ocelot


6

MySQL Connector / Net 6.6 ha una funzionalità per eseguire il debug di stored procedure e funzioni

Installazione del debugger

Per abilitare il debugger della stored procedure:

  • Per Connector / Net 6.6: installare Connector / Net 6.6 e scegliere l'opzione Completo.
  • Per Connector / Net 6.7 e versioni successive: installare il prodotto MySQL per Visual Studio, a cui appartiene il debugger della stored procedure.

Avvio del debugger

Per avviare il debugger, segui questi passaggi:

  • Scegli una connessione in Visual Studio Server Explorer.
  • Espandere la cartella Stored procedure. È possibile eseguire direttamente il debug solo delle stored procedure. Per eseguire il debug di una funzione definita dall'utente, creare un file stored
    procedure che chiami la funzione.
  • Fare clic su un nodo di stored procedure, quindi fare clic con il pulsante destro del mouse e dal menu di scelta rapida scegliere Debug Routine.

5

MySql Connector / NET include anche un debugger di stored procedure integrato in Visual Studio a partire dalla versione 6.6, è possibile ottenere il programma di installazione e la fonte qui: http://dev.mysql.com/downloads/connector/net/

Alcuni documenti / screenshot: https://dev.mysql.com/doc/visual-studio/en/visual-studio-debugger.html

Puoi seguire gli annunci qui: http://forums.mysql.com/read.php?38,561817,561817#msg-561817

AGGIORNAMENTO: MySql per Visual Studio è stato suddiviso da Connector / NET in un prodotto separato, puoi selezionarlo (incluso il debugger) da qui https://dev.mysql.com/downloads/windows/visualstudio/1.2.html (ancora gratuito e open source).

NOTA BENE: Sono stato lo sviluppatore che ha creato il motore di debug delle procedure archiviate per il prodotto MySQL per Visual Studio.


Si è verificato un problema con la stringa di connessione multi-host quando si utilizzano MySQL e Connector .NET. Ho spiegato il problema qui .. Mi chiedevo se qualcuno lo esaminerà? Questo ha causato un bel po 'di problemi a molti di noi sviluppatori .Net che usano MySQL ...
Hooman Bahreini

1
Mi dispiace sentirlo, non lavoro più in Oracle e non ho molto tempo libero, suggerisco di metterti in contatto con il supporto MySQL.
Fernando Gonzalez Sanchez

4

Il primo e stabile debugger per MySQL è in dbForge Studio per MySQL


3

Ho utilizzato due diversi strumenti per eseguire il debug di procedure e funzioni:

  1. dbForge - molte GUI mysql funzionali.
  2. MyDebugger - strumento specializzato per il debug ... pratico strumento per il debug. vota http://tinyurl.com/voteimg

3

La variabile MySQL definita dall'utente (condivisa nella sessione) può essere utilizzata come output di registrazione:

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;

produrrà:

SELECT * FROM foo

1

Toad mysql. Esiste una versione freeware http://www.quest.com/toad-for-mysql/


1
Ho usato Toad per anni ma non sapevo che avesse funzionalità speciali per il debug di sproc. Puoi chiarire come usi Toad per farlo?
Cory House

Ho visto Toad 6.3 per mysql proprio ora, sembra che ci sia una funzione di debug con punti di interruzione e tutto il resto. Vuoi dire che la funzione di debug non funziona? O forse la tua versione è precedente e non include la funzione di debug?
Joyce

1

Risposta corrispondente a questa di @Brad Parks Non sono sicuro della versione di MySQL, ma la mia era 5.6, quindi un po 'di aggiustamento funziona:

Ho creato una funzione debug_msgche è funzione (non procedura) e restituisce testo (nessun limite di caratteri) e quindi chiamo la funzione come SELECT debug_msg(params) AS my_res_set, codice come di seguito:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.