Ce qui permet à SQL Server d'échanger un nom d'objet pour une chaîne passée à une procédure système

13

Pourquoi est-il légal de transmettre un nom d'objet à la procédure stockée système sp_helptext?

Quel mécanisme convertit le nom de l'objet en chaîne?

par exemple

-- works
sp_helptext myproc
sp_helptext [myproc]
sp_helptext [dbo.myproc]
-- and behaves the same as a string
sp_helptext 'myproc'
sp_helptext 'dbo.myproc'

-- does not work
sp_helptext dbo.myproc -- Msg 102, Level 15, State 1, Line 1 incorrect syntax near '.'
-- an additional case that does not work.
sp_helptext [dbo].[myproc] -- Msg 102, Level 15, State 1, Line 1 incorrect syntax

Il semble étrange que je ne sois pas obligé de citer des noms de proc valides, sauf s'il a un .nom de schéma de séparation et un nom de procédure. Je cherche une explication de la façon dont il est converti automatiquement d'un nom entre guillemets en un littéral de chaîne à transmettre comme valeur du paramètre.

Je n'ai pas de problème spécifique à résoudre; Je suis simplement curieux des choses qui ne sont pas documentées.

JJS
la source
Les contributions dans les commentaires ont été déplacées vers cette salle de discussion .
Paul White 9

Réponses:

10

Le premier argument de la procédure stockée système sp_helptextest:

[@objname= ] 'name'
Nom qualifié ou non qualifié d'un objet défini par l'utilisateur et à portée de schéma. Les guillemets ne sont requis que si un objet qualifié est spécifié. Si un nom complet, y compris un nom de base de données, est fourni, le nom de la base de données doit être le nom de la base de données actuelle. L'objet doit se trouver dans la base de données actuelle. le nom est nvarchar(776), sans valeur par défaut.

En outre, la documentation relative aux identificateurs délimités (moteur de base de données) indique:

Utilisation d'identificateurs comme paramètres dans SQL Server
De nombreuses procédures stockées système, fonctions et instructions DBCC prennent les noms d'objets comme paramètres. Certains de ces paramètres acceptent les noms d'objets en plusieurs parties, tandis que d'autres acceptent uniquement les noms en une seule partie. Le fait qu'un nom en une seule partie ou en plusieurs parties soit attendu détermine la façon dont un paramètre est analysé et utilisé en interne par SQL Server.

Noms de
paramètres en une seule partie Si le paramètre est un identificateur en une seule partie, le nom peut être spécifié de la manière suivante:

  • Sans guillemets ni délimiteurs
  • Entouré de guillemets simples
  • Entouré de guillemets doubles
  • Placé entre parenthèses

Noms de paramètres en plusieurs parties Les noms en plusieurs
parties sont des noms qualifiés qui incluent le nom de la base de données ou du schéma ainsi que le nom de l'objet. Lorsqu'un nom en plusieurs parties est utilisé en tant que paramètre, SQL Server requiert que la chaîne complète qui compose le nom en plusieurs parties soit placée dans un ensemble de guillemets simples.


Le premier argument pour sp_helptextaccepter à la fois les noms d'objets en une seule partie (non qualifiés) et en plusieurs parties (qualifiés).

Si l'analyseur T-SQL interprète l'élément après sp_helptextcomme un nom en une seule partie (conformément aux quatre puces ci-dessus), le nom résultant est transmis en tant que valeur d'argument (type de chaîne) attendue par la procédure.

Lorsque l'analyseur le voit comme un nom en plusieurs parties , le texte doit être entouré de guillemets simples comme indiqué.

La caractéristique clé d'un nom en plusieurs parties est un .séparateur (en dehors de tout délimiteur).

Ces exemples de la question sont interprétés avec succès comme des noms en une seule partie:

myproc - en une seule partie (sans guillemets ni délimiteurs - puce # 1)
[myproc] - en une seule partie (entre parenthèses - puce # 4)
'myproc' - en une seule partie (entre guillemets simples - puce # 2)
'dbo.myproc' - multipart avec les guillemets simples requis
[dbo.myproc] - en une seule partie (entre parenthèses - puce # 4)

Les deux derniers exemples de la question sont tous deux analysés en tant que noms de paramètres en plusieurs parties (en raison du .séparateur exposé ). Ils génèrent une erreur car ils ne contiennent pas les guillemets simples englobants requis:

dbo.myproc - multipart sans les guillemets simples requis
[dbo]. [myproc] - multipart sans les guillemets simples requis

Cet exemple supplémentaire utilisant des guillemets doubles a réussi:

"dbo.myproc" - en une seule partie (entre guillemets doubles - puce 3)

Notez qu'il est correctement interprété (pour la valeur du paramètre de procédure) comme étant un nom valide en une seule partie , mais le code de procédure est capable d'interpréter la chaîne (en plusieurs parties) qu'il reçoit de manière flexible (en utilisant PARSENAMEet OBJECTID).

Comme dernier point d'intérêt, notez que l'utilisation de guillemets doubles ici ne dépend pas du réglage de QUOTED_IDENTIFIER.

Paul White 9
la source