什么允许 SQL Server 用对象名称交换传递给系统过程的字符串

JJS*_*JJS 13 sql-server stored-procedures syntax parameter database-internals

是什么导致将对象名称传递给系统存储过程是合法的sp_helptext

什么机制将对象名称转换为字符串?

例如

-- 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
Run Code Online (Sandbox Code Playgroud)

不需要单引号有效的.过程名称似乎很奇怪,除非它具有分隔模式名称和过程名称。我正在寻找有关如何将其从带引号的名称自动转换为要作为参数值传递的字符串文字的解释。

我没有要解决的具体问题;我只是对没有记录的事情感到好奇。

Pau*_*ite 10

系统存储过程的第一个参数sp_helptext是:

[@objname= ] 'name'
是用户定义的架构范围对象的限定名称或非限定名称。仅当指定了限定对象时才需要引号。如果提供了包含数据库名称的完全限定名称,则数据库名称必须是当前数据库的名称。该对象必须在当前数据库中。名称是nvarchar(776),没有默认值。

此外,分隔标识符(数据库引擎)的文档指出:

在 SQL Server 中使用标识符作为参数
许多系统存储过程、函数和 DBCC 语句都将对象名称作为参数。其中一些参数接受多部分对象名称,而其他参数仅接受单部分名称。需要单部分名称还是多部分名称决定了 SQL Server 如何在内部解析和使用参数。

单部分参数名称
如果参数是单部分标识符,可以通过以下方式指定名称:

  • 没有引号或分隔符
  • 用单引号括起来
  • 用双引号括起来
  • 括在括号中

多部分参数名称
多部分名称是包含数据库或模式名称以及对象名称的限定名称。当多部分名称用作参数时,SQL Server 要求将组成多部分名称的完整字符串括在一组单引号中。


第一个参数sp_helptext接受单部分(非限定)和多部分(限定)对象名称。

如果 T-SQL 解析器将后面的项目解释sp_helptext单部分名称(根据上面的四个要点),则结果名称将作为过程期望的(字符串类型)参数值传递。

当解析器将其视为multipart name 时,文本需要按照说明用单引号括起来。

多部分名称的主要特征是.分隔符(在任何分隔符之外)。

问题中的这些示例被成功解释为单部分名称:

myproc - 单部分(不带引号或分隔符 - 项目符号 #1)
[myproc] - 单部分(在括号中 - 项目符号 #4)
'myproc' - 单部分(在单引号中 - 项目符号 #2)
'dbo.myproc' -带有所需单引号的多部分
[dbo.myproc] - 单部分(括号中 - 项目符号 #4)

问题中的最后两个示例都被解析为多部分参数名称(由于暴露的.分隔符)。它们会产生错误,因为它们缺少所需的封闭单引号:

dbo.myproc - 多部分没有所需的单引号
[dbo].[myproc] - multipart 没有所需的单引号

这个使用双引号的额外例子是成功的:

“dbo.myproc” - 单部分(在双引号中 - 要点#3)

请注意,它被成功解释(对于过程参数值)为有效的单部分名称,但过程代码能够灵活地解释它接收的(多部分)字符串(使用PARSENAMEOBJECTID)。

作为最后一个兴趣点,请注意,此处使用双引号不依赖于QUOTED_IDENTIFIER.