Sql-Server

什麼允許 SQL Server 用對象名稱交換傳遞給系統過程的字元串

  • December 12, 2016

是什麼導致將對象名稱傳遞給系統儲存過程是合法的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

不需要單引號有效的過程名稱似乎很奇怪,除非它具有.分離的模式名稱和過程名稱。我正在尋找有關它如何從帶引號的名稱自動轉換為要作為參數值傳遞的字元串文字的解釋。

我沒有要解決的具體問題;我只是對沒有記錄的事情好奇。

系統儲存過程的第一個參數sp_helptext是:

[@objname= ] 'name'

是使用者定義的模式範圍對象的限定或非限定名稱。僅當指定了限定對象時才需要引號。如果提供了完全限定名稱(包括數據庫名稱),則數據庫名稱必須是目前數據庫的名稱。該對象必須在目前數據庫中。名稱是**nvarchar(776)**,沒有預設值。

此外,Delimited Identifiers (Database Engine) 的文件指出:

在 SQL Server 中使用標識符作為參數

許多系統儲存過程、函式和 DBCC 語句都將對象名稱作為參數。其中一些參數接受多部分對象名稱,而其他參數只接受單部分名稱。是否需要單部分或多部分名稱決定了 SQL Server 如何在內部分析和使用參數。

單部分參數名稱

如果參數是單部分標識符,則可以通過以下方式指定名稱:

  • 沒有引號或分隔符
  • 用單引號括起來
  • 用雙引號括起來
  • 括在括號中

多部分參數名稱

多部分名稱是限定名稱,包括數據庫或模式名稱以及對象名稱。當多部分名稱用作參數時,SQL Server 要求將組成多部分名稱的完整字元串括在一組單引號中。


第一個參數sp_helptext接受單部分(非限定)和多部分(限定)對象名稱。

如果 T-SQL 解析器將後面的項目解釋sp_helptext單部分名稱(根據上面的四個要點),則結果名稱將作為過程預期的(字元串類型)參數值傳遞。

當解析器將其視為多部分名稱時,文本需要用單引號括起來,如所述。

多部分名稱的關鍵特性是.分隔符(在任何定界符之外)。

問題中的這些範例成功地解釋為單部分名稱:

myproc - 單部分(不帶引號或分隔符 - 項目符號 #1)
[myproc] - 單部分(在括號中 - 項目符號 #4)
'myproc' - 單部分(在單引號中 - 項目符號 #2)
'dbo.myproc' -帶有所需單引號的**多部分**
[dbo.myproc] - 單部分(在括號中 - 項目符號 #4)

問題的最後兩個範例都被解析為多部分參數名稱(由於暴露的.分隔符)。它們會產生錯誤,因為它們缺少必需的封閉單引號:

dbo.myproc - 不帶所需單引號的多部分
[dbo].[myproc] - 不帶所需單引號的多部分

這個使用雙引號的額外範例是成功的:

“dbo.myproc” - 單部分(雙引號中 - 要點 #3)

請注意,它被成功解釋為(對於過程參數值)為有效的單部分名稱,但過程程式碼能夠靈活地解釋它接收到的(多部分)字元串(使用PARSENAMEand OBJECTID)。

作為最後一點,請注意這裡使用雙引號並不依賴於QUOTED_IDENTIFIER.

引用自:https://dba.stackexchange.com/questions/155526