web-dev-qa-db-fra.com

Instruction PRINT dans T-SQL

Pourquoi l'instruction PRINT dans T-SQL semble-t-elle ne fonctionner que parfois? Quelles sont les contraintes d'utilisation? Il semble parfois que si un jeu de résultats est généré, il devient une fonction nulle. Je suppose que cela empêche de corrompre le jeu de résultats, mais sa sortie pourrait-elle ne pas sortir dans un autre jeu de résultats, tel que le nombre de lignes?

66
ProfK

Donc, si vous avez une déclaration semblable à celle-ci, vous dites que vous n'obtenez aucun résultat «imprimé»?

sélectionnez * parmi sysobjects 
 PRINT 'vient de sélectionner * parmi sysobjects'

Si vous utilisez SQL Query Analyzer, vous verrez qu'il y a deux onglets en bas, l'un d'eux est "Messages" et c'est là que les instructions "print" apparaissent.
Si vous êtes préoccupé par le timing de voir les déclarations imprimées, vous pouvez essayer d'utiliser quelque chose comme

raiserror ('My Print Statement', 10,1) avec nowait

Cela vous donnera immédiatement le message dès que l'instruction est atteinte, plutôt que de mettre la sortie en mémoire tampon, comme le fera l'Analyseur de requêtes dans la plupart des conditions.

92
David T. Macknet

L'instruction Print dans TSQL est une créature mal comprise, probablement à cause de son nom. En fait, il envoie un message au mécanisme de traitement des erreurs/messages qui le transfère ensuite à l'application appelante. IMPRIMER est assez bête. Vous ne pouvez envoyer que 8 000 caractères (4 000 caractères Unicode). Vous pouvez envoyer une chaîne littérale, une variable de chaîne (varchar ou char) ou une expression de chaîne. Si vous utilisez RAISERROR, vous êtes limité à une chaîne de 2 044 caractères. Cependant, il est beaucoup plus facile de l'utiliser pour envoyer des informations à l'application appelante, car elle appelle une fonction de formatage similaire à l'ancienne printf de la bibliothèque standard C. RAISERROR peut également spécifier un numéro d'erreur, une gravité et un code d'état en plus du message texte. Il peut également être utilisé pour renvoyer des messages définis par l'utilisateur créés à l'aide de la procédure stockée système sp_addmessage. Vous pouvez également forcer l'enregistrement des messages.

Vos routines de traitement des erreurs ne serviront pas à recevoir des messages, même si les messages et les erreurs sont si semblables. Bien entendu, la technique varie en fonction de la manière dont vous vous connectez à la base de données (OLBC, OLEDB, etc.). Pour recevoir et traiter les messages du moteur de base de données SQL Server, lorsque vous utilisez System.Data.SQLClient, vous devez créer un délégué SqlInfoMessageEventHandler, identifiant la méthode qui gère l'événement, pour écouter l'événement InfoMessage. sur la classe SqlConnection. Vous constaterez que les informations de contexte de message, telles que la gravité et l'état, sont transmises en tant qu'arguments au rappel, car du point de vue du système, ces messages ressemblent à des erreurs.

Il est toujours judicieux de pouvoir insérer ces messages dans votre application, même si vous ne faites que mettre en file d'attente dans un fichier, car ils seront toujours utiles si vous essayez de résoudre un problème très obscur. Cependant, je ne peux pas penser que je ne souhaite pas que les utilisateurs finaux les voient à moins que vous ne puissiez réserver un niveau d’information affichant des éléments dans l’application.

36
Phil_Factor

Query Analyzer tamponne les messages. Les instructions PRINT et RAISERROR utilisent toutes les deux ce tampon, mais l'instruction RAISERROR comporte une option WITH NOWAIT. Pour imprimer un message immédiatement, utilisez ce qui suit:

RAISERROR ('Your message', 0, 1) WITH NOWAIT

RAISERROR n’affiche que 400 caractères de votre message et utilise une syntaxe similaire à la fonction C printf pour la mise en forme du texte.

Veuillez noter que l'utilisation de RAISERROR avec l'option WITH NOWAIT videra le tampon de messages, ainsi toutes les informations précédemment tamponnées seront également affichées.

24
JimCarden

Je me suis récemment retrouvé dans cette situation et c'est parce que j'avais une instruction convert sur une variable null. Etant donné que cela causait des erreurs, l’instruction d’impression entière affichait la valeur null et n’imprimait pas du tout.

Exemple - Cela échouera:

declare @myID int=null
print 'First Statement: ' + convert(varchar(4), @myID)

Exemple - Ceci imprimera:

declare @myID int=null
print 'Second Statement: ' +  coalesce(Convert(varchar(4), @myID),'@myID is null')
20
WEFX

Pour le bénéfice de tous ceux qui liront cette question et qui manquent réellement d'instructions print de leur sortie, il existe en fait des cas où l'impression est exécutée mais n'est pas renvoyée au client. Je ne peux pas vous dire précisément ce qu'ils sont. Je peux vous dire que si vous mettez une instruction go immédiatement avant et après toute instruction print, vous la verrez si elle est exécutée.

3
JohnOpincar

Avez-vous des variables associées à ces instructions d'impression déjà sorties? Si tel est le cas, j'ai constaté que si la variable n'avait pas de valeur, l'instruction print ne serait pas sortie.

0
user2574678