web-dev-qa-db-fra.com

SQL Server / T-SQL prend-il en charge la continuation de ligne pour rompre les longues chaînes?

J'ai parfois un script SQL qui a une ou plusieurs chaînes super longues (parfois même stupides). Il s'agit généralement de VARBINARY littéraux/constantes qui représentent des fichiers/assemblys, mais il s'agit parfois de texte.

Le problème principal avec les chaînes très longues est que certains éditeurs de texte ne les gèrent pas très bien. Par exemple, j'ai un littéral VARBINARY que j'utilise dans un CREATE Assembly [AssemblyName] FROM 0x...., et l'assemblage lui-même fait un peu plus de 1 Mo, ce qui équivaut à un peu plus de 2 millions de caractères dans un fichier texte, car chaque octet nécessite que deux caractères soient représentés en notation hexadécimale (par exemple 0x1F = a 1 et un F). SQL Server Management Studio (SSMS) ne gère pas bien cela et se bloque pendant plusieurs secondes alors que j'essaie de faire défiler cette ligne. Et en fait, certaines versions (je ne sais pas si cela se produit toujours) afficheront même un avertissement sur les longues lignes lors de l'ouverture d'un script qui a au moins une ligne sur une certaine longueur.

Un problème secondaire est qu'il complique la mise en forme lors de l'utilisation dans un éditeur sans habillage Word activé ou lors de la publication en ligne. Le problème ici est que le curseur de la barre de défilement horizontale est très étroit et le déplacer ne serait-ce qu'un tout petit peu fait défiler le texte non super long hors de la vue.

Maintenant, T-SQL ne termine pas les commandes avec des retours à la ligne ou même des points-virgules (bien que les points-virgules soient préférés/recommandés, à partir de SQL Server 2005). Ainsi, puisque SQL Server sait comment analyser chaque instruction de manière à savoir quand elle se termine, il semble que la ligne longue soit divisée en plusieurs lignes, séparées uniquement par un newline / carriage-return + line-feed, ne semble pas déraisonnable. Mais cela ne fonctionne pas dans les deux cas.

PRINT 'Line1
Line2';

renvoie (dans l'onglet "Messages"):

Line1
Line2

Et cela est suffisamment logique car la nouvelle ligne est dans un littéral/constant. Mais faire cela pour un VARBINARY ne fonctionne pas non plus.

PRINT 0x1234
5678;

me donne une erreur.

13
Solomon Rutzky

Heureusement, la poursuite de la ligne dans T-SQL est prise en charge via le \ (barre oblique inverse). Il suffit de placer cela à la fin d'une ligne, juste avant le newline / carriage-return + line-feedet la nouvelle ligne sera ignorée.

Pour les chaînes de texte, cela se comporte comme suit:

PRINT 'Line1\
Line2';

renvoie (dans l'onglet "Messages"):

Line1Line2

Pour les chaînes binaires/hexadécimales, cela se comporte comme suit:

PRINT 0x1234\
5678;

renvoie (dans l'onglet "Messages"):

0x12345678;

Afin de formater les fichiers binaires (assemblys, certificats) en chaînes de texte hexadécimales à utiliser dans les scripts SQL, j'ai écrit un utilitaire de ligne de commande appelé BinaryFormatter que j'ai publié en open-source sur GitHub. Non seulement il convertit le fichier binaire en une représentation textuelle, mais il utilise également la continuation de ligne pour répartir de longs littéraux VARBINARY sur autant de lignes que nécessaire, en fonction du nombre de caractères spécifié à utiliser pour chaque ligne. Le résultat est quelque chose comme:

4D5A09DE34F178313345A4\
00007F4E39782EFC48D842\
00000000

que je copie puis colle dans mon script, comme indiqué dans le {...} zone ci-dessous:

CREATE Assembly [AssemblyName]
FROM 0x\
{output from BinaryFormatter}
;

Pour plus de détails sur ce sujet, veuillez consulter mon billet de blog: Line-Continuation in T-SQL

13
Solomon Rutzky