Eu tenho um procedimento armazenado de execução muito longa no SQL Server 2005 que estou tentando depurar e estou usando o comando 'print' para fazer isso. O problema é que estou recebendo apenas as mensagens do SQL Server no final do meu sproc - eu gostaria de liberar o buffer de mensagens e vê-las imediatamente durante o tempo de execução do sproc, e não no momento fim.
sql-server
tsql
printing
Erik Forbes
fonte
fonte
Respostas:
Use a
RAISERROR
função:Você não deve substituir completamente todas as suas impressões por raiserror. Se você tiver um loop ou cursor grande em algum lugar, faça-o uma ou duas vezes por iteração ou mesmo a cada várias iterações.
Além disso: eu aprendi sobre RAISERROR neste link, que agora considero a fonte definitiva no tratamento de erros do SQL Server e definitivamente vale a pena ler:
http://www.sommarskog.se/error-handling-I.html
fonte
Com base na resposta de @JoelCoehoorn, minha abordagem é deixar todas as minhas declarações PRINT no lugar e simplesmente segui-las com a declaração RAISERROR para causar o flush.
Por exemplo:
A vantagem dessa abordagem é que as instruções PRINT podem concatenar seqüências de caracteres, enquanto o RAISERROR não pode. (Portanto, de qualquer forma, você tem o mesmo número de linhas de código, pois teria que declarar e definir uma variável para usar no RAISERROR).
Se, como eu, você usar o AutoHotKey ou o SSMSBoost ou uma ferramenta equivalente, poderá configurar facilmente um atalho como "] flush" para inserir a linha RAISERROR para você. Isso economiza tempo se for sempre a mesma linha de código, ou seja, não precisar ser personalizado para conter texto ou variável específica.
fonte
RAISERROR()
suportaprintf()
interpolação de cadeia no estilo. Por exemplo, se@MyVariableName
é um tipo stringish (por exemplo,VARCHAR(MAX)
,NVARCHAR(MAX)
, etc.), você pode usarRAISERROR()
com uma linha:RAISERROR(N'MyVariableName: %s', 0, 1, @MyVariableName)
.Sim ... O primeiro parâmetro da função RAISERROR precisa de uma variável NVARCHAR. Então tente o seguinte;
OU
fonte
Outra opção melhor é não depender de PRINT ou RAISERROR e apenas carregar suas instruções "print" em uma tabela ## Temp no TempDB ou em uma tabela permanente em seu banco de dados que lhe dará visibilidade dos dados imediatamente através de uma instrução SELECT de outra janela . Isso funciona melhor para mim. O uso de uma tabela permanente também serve como um log para o que aconteceu no passado. As instruções de impressão são úteis para erros, mas, usando a tabela de log, você também pode determinar o ponto exato da falha com base no último valor registrado para essa execução específica (supondo que você rastreie o horário de início da execução geral na tabela de log).
fonte
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
sua sessão de monitoramentoREAD UNCOMMITTED
transação para outra tabela, mas provavelmente perde o momento imediatamente antesROLLBACK
. Portanto, provavelmente resolve o 'quão longe?' não o 'por que retroceder?'Apenas para referência, se você trabalha em scripts (processamento em lote), não em procedimento armazenado , a saída de liberação é acionada pelo comando GO, por exemplo
Em geral, minha conclusão é a seguinte: a saída da execução do script mssql, executada na GUI do SMS ou com sqlcmd.exe, é liberada para arquivo, stdoutput, janela da GUI na primeira instrução GO ou até o final do script.
A descarga dentro do procedimento armazenado funciona de maneira diferente, pois você não pode colocar o GO dentro.
Referência: instrução tsql Go
fonte
go
não apenas libera a saída, finaliza o lote conforme o link que você forneceu. Tudo o que vocêdeclare
d é descartado, portanto, não é muito útil para depuração.declare @test int print "I want to read this!" go set @test=5
você ainda não conseguiu@test
definir uma reivindicação de erro porque está em um novo lote.