Como você depura procedimentos armazenados do MySQL?


125

Meu processo atual para depurar procedimentos armazenados é muito simples. Eu crio uma tabela chamada "debug" onde insiro valores variáveis ​​do procedimento armazenado enquanto ele é executado. Isso me permite ver o valor de qualquer variável em um determinado ponto do script, mas existe uma maneira melhor de depurar os procedimentos armazenados do MySQL?


2
Existem opções de GUI para usuários não Windows? Ter que executar uma cópia do Windows apenas para depurar procedimentos armazenados é um salto. E a maioria das opções de inserção de tabela falha se você estiver em uma transação que está prestes a reverter.
Code Abominator

Respostas:


44

Eu faço algo muito parecido com você.

Normalmente incluirei um parâmetro DEBUG que padroniza como false e posso definir como true em tempo de execução. Em seguida, envolva as instruções de depuração em um bloco "If Debug".

Também uso uma tabela de registro em log de muitos dos meus trabalhos, para que eu possa revisar processos e prazos. Meu código de depuração obtém saída também. Incluo o nome do parâmetro de chamada, uma breve descrição, a contagem de linhas afetadas (se apropriado), um campo de comentários e um carimbo de data / hora.

Boas ferramentas de depuração são uma das tristes falhas de todas as plataformas SQL.


3
Nem todas as plataformas @Bob Probst, a Sybase ferramentas de depuração são tranquilos decente com depuração ponto de interrupção para procedimentos de gatilho e armazenados
Anup

69

O debug_msgprocedimento a seguir pode ser chamado para simplesmente gerar uma mensagem de depuração no 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 ;

Em seguida, execute o teste assim:

CALL test_procedure(1,2)

Isso resultará na seguinte saída:

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

8
Isso não parece funcionar para FUNCTIONS e não faço ideia do porquê. Ele sempre fornece "Código de erro: 1415. Não é permitido retornar um conjunto de resultados de uma função". Existe algum recurso?
Patrick M

1
As funções do @PatrickM não podem retornar linhas ("resultado") enquanto esse procedimento de depuração depende dele (as mensagens de depuração são conjuntos de resultados retornados na chamada de procedimento). Em funções, você só pode INSERT INTO my_log_table (message) VALUES (msg)e talvez recuperar todas as mensagens de depuração, uma vez chamadas de função são mais (ou seja: você está de volta no procedimento)
Xenos

Essa abordagem é boa, mas escrever no console não é eficaz no MySQL Workbench como IDEs. porque cada instrução "select" abre um novo painel de resultados. Eu acho que é melhor para criar uma tabela log temporário para registrar mensagens de erro com carimbo de tempo e nome do procedimento
Mustafa Kemal atum

28

Sim, existem ferramentas especializadas para esse tipo de coisa - MySQL Debugger .
insira a descrição da imagem aqui


5
eu estava tão ansioso para experimentar. Infelizmente, são destroços totais. Recebo a mensagem de erro "função que não existe" no mysql, como resultado, a GUI se ramifica incorretamente através do código SP (embora o MySQL a execute corretamente). Sem mencionar as variáveis ​​locais "DECLARE var DEFAULT value". Eles apenas aparecem como NULL quando claramente não são. Ah, e também "Identificador não declarado: 'FETCH_RADIUS_DISTSORT'", onde essa foi uma declaração compilada. Não recomendado.
Kellogs # 8/13

4
Não é perfeito, mas meu julgamento com isso foi uma experiência muito diferente da relatada por @kellogs acima. A ferramenta é agradável e leve e parece fazer o trabalho necessário sem inchaço. Foi uma experiência muito melhor para mim do que qualquer outra ferramenta testada (por exemplo, Visual Studio, Toad e dbForge Studio, todos com grandes falhas - descreveriam tudo isso como "destroços totais" em comparação). Não tenho certeza se isso ocorre porque a função que está sendo depurada não incluiu nenhuma das construções defeituosas ou se os problemas foram corrigidos.
Steve Chambers

2
Eu também achei essa ferramenta bastante útil para depurar meus procedimentos armazenados.
Ralfe

22

Como depurar um procedimento armazenado do MySQL.

Depurador do homem pobre:

  1. Crie uma tabela chamada logtable com duas colunas id INTe log VARCHAR(255).

  2. Faça o incremento automático da coluna de identificação.

  3. Use este procedimento:

    delimiter //
    DROP PROCEDURE `log_msg`//
    CREATE PROCEDURE `log_msg`(msg VARCHAR(255))
    BEGIN
        insert into logtable select 0, msg;
    END
  4. Coloque esse código em qualquer lugar que você deseja registrar uma mensagem na tabela.

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

É um bom pequeno logger, rápido e sujo, para descobrir o que está acontecendo.



10

O depurador para mysql foi bom, mas não é gratuito. Isto é o que eu uso agora:

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$

Uso no procedimento armazenado:

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

uso do procedimento armazenado:

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

8

Outra maneira é apresentada aqui

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

com procedimentos personalizados de depuração mySql e tabelas de log.

Você também pode simplesmente colocar uma seleção simples no seu código e ver se ele é executado.

SELECT 'Message Text' AS `Title`; 

Eu recebi essa ideia de

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

Também alguém criou um modelo para procedimentos de depuração personalizados no GitHub.

Veja aqui

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

Foi mencionado aqui

Como capturar qualquer exceção nos gatilhos e armazenar procedimentos para o mysql?


7

Simplesmente coloco instruções de seleção nas principais áreas do procedimento armazenado para verificar o status atual dos conjuntos de dados e, em seguida, comento-as (--selecione ...) ou remova-as antes da produção.


7

Estou atrasado para a festa, mas trouxe mais cerveja:

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

Eu tentei, e parece bastante estável, suportando pontos de interrupção e inspeção variável.

Não é uma suíte completa (apenas 4,1 Mb), mas me ajudou muito!

Como funciona: Ele se integra ao seu cliente mysql (estou usando o Ubuntu 14.04) e depois que você executa:

$install
$setup yourFunctionName

Ele instala um novo banco de dados no seu servidor, que controla o processo de depuração. Assim:

$debug yourFunctionName('yourParameter')

lhe dará a chance de caminhar passo a passo seu código e, "atualizando" suas variáveis, você poderá visualizar melhor o que está acontecendo dentro do seu código.

Dica importante: durante a depuração, talvez você altere (recrie o procedimento). Após uma recriação, execute: $ exit e $ setup antes de um novo $ debug

Essa é uma alternativa aos métodos "inserir" e "log". Seu código permanece livre de instruções adicionais de "depuração".

Captura de tela:

passo do ponto de interrupção da jaguatirica


6

O MySQL Connector / Net 6.6 possui um recurso para depurar procedimentos e funções armazenados

Instalando o depurador

Para habilitar o depurador do procedimento armazenado:

  • Para Connector / Net 6.6: Instale o Connector / Net 6.6 e escolha a opção Concluir.
  • Para Connector / Net 6.7 e posterior: Instale o produto MySQL para Visual Studio, ao qual o depurador de procedimento armazenado pertence.

Iniciando o depurador

Para iniciar o depurador, siga estas etapas:

  • Escolha uma conexão no Visual Studio Server Explorer.
  • Expanda a pasta Procedimentos armazenados. Somente procedimentos armazenados podem ser depurados diretamente. Para depurar uma função definida pelo usuário, crie um
    procedimento armazenado que chama a função.
  • Clique em um nó de procedimento armazenado, clique com o botão direito do mouse e, no menu de contexto, escolha Debug Routine.

5

O MySql Connector / NET também inclui um depurador de procedimento armazenado integrado no visual studio a partir da versão 6.6. Você pode obter o instalador e a fonte aqui: http://dev.mysql.com/downloads/connector/net/

Algumas documentações / capturas de tela: https://dev.mysql.com/doc/visual-studio/en/visual-studio-debugger.html

Você pode seguir os avisos aqui: http://forums.mysql.com/read.php?38,561817,561817#msg-561817

ATUALIZAÇÃO: O MySql para Visual Studio foi dividido do Connector / NET em um produto separado. Você pode selecioná-lo (incluindo o depurador) aqui https://dev.mysql.com/downloads/windows/visualstudio/1.2.html (ainda código aberto e gratuito).

AVISO LEGAL: Eu fui o desenvolvedor que criou o mecanismo de depurador de procedimentos armazenados para o produto MySQL for Visual Studio.


Há um problema com a cadeia de conexão de vários hosts ao usar o MySQL e o Connector .NET. Eu expliquei o problema aqui ... Eu queria saber se alguém vai olhar para isso? Isto tem causado um pouco de problema para muitos dos desenvolvedores nos .Net que usam MySQL ...
Hooman Bahreini

1
Lamento saber que, não trabalho mais na Oracle e não tenho muito tempo livre, sugiro entrar em contato com o suporte ao MySQL.
Fernando Gonzalez Sanchez

4

O primeiro e estável depurador para MySQL está no dbForge Studio for MySQL


3

Eu tinha usado duas ferramentas diferentes para depurar procedimentos e funções:

  1. dbForge - muitos GUI mysql funcional.
  2. MyDebugger - ferramenta especializada para depuração ... ferramenta útil para depuração. vote http://tinyurl.com/voteimg

3

A variável definida pelo usuário do MySQL (compartilhada na sessão) pode ser usada como saída de log:

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;

irá produzir:

SELECT * FROM foo

1

Sapo mysql. Existe uma versão freeware http://www.quest.com/toad-for-mysql/


1
Eu uso o Toad há anos, mas não sabia que tinha recursos especiais para depurar sprocs. Você pode esclarecer como usa o Toad para fazer isso?
Cory Casa

Olhei para o Toad 6.3 para mysql agora, parece que existe um recurso de depuração com pontos de interrupção e tudo mais. Você quer dizer que o recurso de depuração não está funcionando? Ou talvez sua versão seja mais antiga e não inclua o recurso de depuração?
Joyce

1

Resposta correspondente a esta @Brad Parks Não tenho certeza sobre a versão do MySQL, mas a minha era a 5.6, portanto, um pouco de ajustes funciona:

Eu criei uma função debug_msgque é função (não procedimento) e retorna texto (sem limite de caracteres) e, em seguida, chamo a função como SELECT debug_msg(params) AS my_res_set, código como abaixo:

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.