J'ai une procédure stockée très longue dans SQL Server 2005 que j'essaie de déboguer, et j'utilise la commande «imprimer» pour le faire. Le problème est que je ne récupère les messages que de SQL Server à la toute fin de mon sproc - j'aimerais pouvoir vider le tampon de messages et voir ces messages immédiatement pendant l'exécution du sproc, plutôt qu'à l'extrême fin.
sql-server
tsql
printing
Erik Forbes
la source
la source
Réponses:
Utilisez la
RAISERROR
fonction:Vous ne devez pas remplacer complètement toutes vos impressions par raiserror. Si vous avez une boucle ou un gros curseur quelque part, faites-le une ou deux fois par itération ou même toutes les plusieurs itérations.
Aussi: J'ai d'abord entendu parler de RAISERROR sur ce lien, que je considère maintenant comme la source définitive de la gestion des erreurs SQL Server et qui vaut vraiment la peine d'être lu:
http://www.sommarskog.se/error-handling-I.html
la source
En s'appuyant sur la réponse de @JoelCoehoorn, mon approche consiste à laisser toutes mes instructions PRINT en place et à les suivre simplement avec l'instruction RAISERROR pour provoquer le vidage.
Par exemple:
L'avantage de cette approche est que les instructions PRINT peuvent concaténer des chaînes, contrairement à RAISERROR. (Donc, dans les deux cas, vous avez le même nombre de lignes de code, car vous devez déclarer et définir une variable à utiliser dans RAISERROR).
Si, comme moi, vous utilisez AutoHotKey ou SSMSBoost ou un outil équivalent, vous pouvez facilement configurer un raccourci tel que "] flush" pour entrer la ligne RAISERROR pour vous. Cela vous fait gagner du temps s'il s'agit de la même ligne de code à chaque fois, c'est-à-dire qu'il n'a pas besoin d'être personnalisé pour contenir du texte spécifique ou une variable.
la source
RAISERROR()
prend en charge l'printf()
interpolation de chaîne de style. Par exemple, si@MyVariableName
est un type de stringish (par exempleVARCHAR(MAX)
,NVARCHAR(MAX)
etc.), vous pouvez utiliserRAISERROR()
avec une seule ligne:RAISERROR(N'MyVariableName: %s', 0, 1, @MyVariableName)
.Oui ... Le premier paramètre de la fonction RAISERROR a besoin d'une variable NVARCHAR. Essayez donc ce qui suit;
OU
la source
Une autre meilleure option est de ne pas dépendre de PRINT ou RAISERROR et de simplement charger vos instructions "print" dans une table ## Temp dans TempDB ou une table permanente dans votre base de données qui vous donnera une visibilité immédiate des données via une instruction SELECT à partir d'une autre fenêtre . Cela fonctionne le mieux pour moi. L'utilisation d'une table permanente sert également de journal à ce qui s'est passé dans le passé. Les instructions d'impression sont pratiques pour les erreurs, mais en utilisant la table des journaux, vous pouvez également déterminer le point d'échec exact en fonction de la dernière valeur enregistrée pour cette exécution particulière (en supposant que vous suiviez l'heure de début d'exécution globale dans votre table des journaux.)
la source
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
dans votre session de surveillanceREAD UNCOMMITTED
transaction dans une autre table, mais vous manquez probablement l'instant juste avantROLLBACK
. Donc, cela résout probablement le «jusqu'où? pas le "pourquoi le retour en arrière?"Juste pour la référence, si vous travaillez dans des scripts (traitement par lots), pas dans une procédure stockée , la sortie de vidage est déclenchée par la commande GO, par exemple
En général, ma conclusion est la suivante: la sortie de l'exécution du script mssql, exécutée dans l'interface graphique SMS ou avec sqlcmd.exe, est vidée dans le fichier, stdoutput, la fenêtre gui lors de la première instruction GO ou jusqu'à la fin du script.
Le vidage à l'intérieur des procédures stockées fonctionne différemment, car vous ne pouvez pas placer GO à l'intérieur.
Référence: déclaration tsql Go
la source
go
ne se contente pas de vider la sortie, il termine le lot selon le lien que vous avez fourni. Tout ce que vous avezdeclare
supprimé est donc peu utilisable pour le débogage.declare @test int print "I want to read this!" go set @test=5
sera bien que vous une revendication d'erreur@test
n'est pas définie car elle est dans un nouveau lot.