Pergunta

Eu tenho vários procedimentos pl/sql que podem levar vários minutos para serem executados.Ao desenvolvê-los, adicionei algumas instruções de impressão para ajudar na depuração e também fornecer alguns comentários e indicadores de progresso.Inicialmente, executei-os em pequenos conjuntos de testes e o resultado foi quase instantâneo.Agora que estou testando conjuntos de testes maiores que levam vários minutos para serem executados, descobri que imprimir no console não é mais adequado, porque nada é impresso até que o procedimento termine.Estou acostumado a trabalhar em ambientes que não armazenam em buffer sua saída e a imprimem imediatamente, e é comum adicionar instruções de impressão simples para depuração e diagnóstico simples.

É possível em pl/sql imprimir a saída imediatamente (sem buffer)?Caso contrário, que alternativas as pessoas recomendam para obter um resultado semelhante?

Foi útil?

Solução

Você pode ter um procedimento que grava mensagens em uma tabela usando uma transação autônoma algo como:

procedure log (p_message)
is
    pragma autonomous_transaction;
begin
    insert into message_log (user, datetime, message)
    values (user, sysdate, p_message);
    commit;
end;

Em seguida, monitore a tabela de outra sessão do Oracle.

Outras dicas

temos um pequeno truque para isso.

você pode usar DBMS_APPLICATION_INFO.set_client_info("algumas informações aqui");criando algumas variáveis ​​e substituindo a string dentro de " ".

e use select client_info from v$session para monitorar o progresso.

Eu tenho usado dbms_pipe para esse fim. Envie mensagens para um tubo nomeado e leia -as de outra sessão. Esse método pode não funcionar em um ambiente RAC quando os processos de redação e leitura podem se conectar a um nó diferente.

Como alternativa, você pode inserir mensagens em uma tabela usando um procedimento executado em sua própria sessão usando "Pragma Autonomous_transaction". Você pode consultar essas mensagens de outra sessão

EDIT: Vejo que minha segunda opção já foi mencionada.

Geralmente existem duas opções:

  • Envie a saída para uma tabela Oracle (ou tabela temporária)
  • Escreva no sistema de arquivos (host de banco de dados) com utl_file

Se você não tiver acesso ao SO ao host do banco de dados, ainda poderá gravar no sistema de arquivos DBHOST e vincular uma tabela definida externamente do Oracle ao arquivo para que ele possa ser consultado com uma seleção.

Pode depender da sua ferramenta cliente. Não usei o SQL*Plus há algum tempo, mas quando estou depurando procedimentos no desenvolvedor PL/SQL, abro uma janela de comando e emito um SET SERVEROUTPUT ON comando. Então, quando eu executo o procedimento, qualquer coisa impressa por DBMS_OUTPUT.PUT_LINE aparece imediatamente.

EDIT: Você está certo, acho que só estava vendo isso com quantidades maiores de saída ou algo assim. De qualquer forma, eu fiz algumas pesquisas online e me deparei com isso log4plsql - pode ser útil.

Uma alternativa é usar uma função de pipeline que retorne suas informações de registro. Veja aqui um exemplo: http://berxblog.blogspot.com/2009/01/pipelined-function-vs-dbmsoutput.html Quando você usa uma função de pipeline, não precisa usar outra sessão SQLPlus/Toad/SQL etc ....

Você pode usar o tubo DBMS e o visualizador de tubos no desenvolvedor PL/SQL para capturar de maneira assíncrona todos os Infos à medida que são colocados no tubo.

Tenha cuidado para colocar apenas as coisas em um cano quando houver alguém para lê -lo. Caso contrário, sua chamada falhará quando o tubo estiver cheio.

Há também a possibilidade de usar eventos, o desenvolvedor PL/SQL também possui um monitor de eventos. E os documentos devem fornecer um exemplo de como fazê -lo.

Outra opção é fazer com que seu PL/SQL ligue para um procedimento para enviar um email com a mensagem de log nele. Isso exige que seu banco de dados tenha um recurso de envio de email, que pode ser adicionado usando o UTL_SMTP.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top