Что позволяет SQL Server обменивать имя объекта на строку, переданную системной процедуре

13

Что делает законным передачу имени объекта системной хранимой процедуре 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

Кажется странным, что я не обязан заключать в кавычки действительные имена процедур, если только у них нет .разделяющего имени схемы и имени процедуры. Я ищу объяснение того, как он автоматически конвертируется из имени в кавычках в строковый литерал для передачи в качестве значения параметра.

У меня нет конкретной проблемы для решения; Я просто интересуюсь вещами, которые не задокументированы.

JJS
источник
Вклады в комментариях были перемещены в эту комнату чата .
Пол Уайт 9

Ответы:

10

Первый аргумент системной хранимой процедуры sp_helptext:

[@objname= ] 'name'
Полное или неквалифицированное имя определенного пользователем объекта области схемы. Кавычки требуются, только если указан квалифицированный объект. Если указано полное имя, включая имя базы данных, имя базы данных должно быть именем текущей базы данных. Объект должен находиться в текущей базе данных. имя nvarchar(776)без указания по умолчанию.

Кроме того, документация для идентификаторов с разделителями (компонент 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 - multipart без обязательных одинарных кавычек
[dbo]. [myproc] - составная часть без обязательных одинарных кавычек

Этот дополнительный пример с использованием двойных кавычек успешен:

«dbo.myproc» - одна часть (в двойных кавычках - пункт № 3)

Обратите внимание, что оно успешно интерпретируется (для значения параметра процедуры) как допустимое однокомпонентное имя, но код процедуры способен гибко интерпретировать (составную) строку, которую он получает (используя PARSENAMEи OBJECTID).

В качестве последнего интереса отметим, что использование двойных кавычек здесь не зависит от настройки QUOTED_IDENTIFIER.

Пол Уайт 9
источник