Co umożliwia programowi SQL Server zamianę nazwy obiektu na ciąg przekazywany do procedury systemowej

13

Co powoduje, że legalne jest przekazywanie nazwy obiektu do procedury przechowywanej w systemie sp_helptext?

Jaki mechanizm konwertuje nazwę obiektu na ciąg?

na przykład

-- 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

Wydaje się dziwne, że nie jestem zobowiązany do apostrof poprawnych nazw proc, chyba że ma .oddzielającą nazwę schematu i nazwę postępowania. Szukam wyjaśnienia, w jaki sposób jest automatycznie konwertowane z cytowanej nazwy na literał łańcuchowy, który ma zostać przekazany jako wartość parametru.

Nie mam konkretnego problemu do rozwiązania; Jestem po prostu dociekliwy w sprawach, które nie są udokumentowane.

JJS
źródło
Treści w komentarzach zostały przeniesione do tego pokoju czatu .
Paul White 9

Odpowiedzi:

10

Pierwszy argument systemowej procedury składowanej sp_helptextto:

[@objname= ] 'name'
Jest kwalifikowaną lub niekwalifikowaną nazwą zdefiniowanego przez użytkownika obiektu o zasięgu schematu. Znaki cudzysłowu są wymagane tylko wtedy, gdy określono kwalifikowany obiekt. Jeśli podano pełną nazwę, w tym nazwę bazy danych, nazwa bazy danych musi być nazwą bieżącej bazy danych. Obiekt musi znajdować się w bieżącej bazie danych. nazwa jest nvarchar(776)bez domyślnych.

Ponadto dokumentacja dla identyfikatorów rozdzielanych (aparat bazy danych) stanowi:

Używanie identyfikatorów jako parametrów w SQL Server
Wiele procedur przechowywanych w systemie, funkcji i instrukcji DBCC przyjmuje nazwy obiektów jako parametry. Niektóre z tych parametrów akceptują nazwy obiektów wieloczęściowych, podczas gdy inne akceptują tylko nazwy pojedynczych części. To, czy oczekiwana jest nazwa pojedynczej części czy nazwy wieloczęściowej, określa, w jaki sposób parametr jest analizowany i używany wewnętrznie przez SQL Server.

Nazwy
parametrów jednoczęściowych Jeśli parametr jest identyfikatorem jednoczęściowym, nazwę można określić na następujące sposoby:

  • Bez cudzysłowów i ograniczników
  • Ujęte w pojedyncze cudzysłowy
  • Ujęte w podwójny cudzysłów
  • Otoczony w nawiasach

Nazwy parametrów wieloczęściowych Nazwy
wieloczęściowe to kwalifikowane nazwy, które obejmują nazwę bazy danych lub schematu, a także nazwę obiektu. Gdy nazwa wieloczęściowa jest używana jako parametr, SQL Server wymaga, aby pełny ciąg znaków składający się na nazwę wieloczęściową był zawarty w zestawie pojedynczych cudzysłowów.


Pierwszy argument, który sp_helptextakceptuje zarówno nazwy obiektów jednoczęściowe (niekwalifikowane), jak i wieloczęściowe (kwalifikowane).

Jeśli parser T-SQL interpretuje element sp_helptextjako nazwę pojedynczej części (zgodnie z czterema punktorami powyżej), wynikowa nazwa jest przekazywana jako wartość argumentu (typu ciągu) oczekiwana przez procedurę.

Gdy parser widzi to jako nazwę składającą się z wielu części , tekst musi być otoczony pojedynczymi cudzysłowami, jak podano.

Kluczową cechą nazwy wieloczęściowej jest .separator (poza ogranicznikami).

Te przykłady z pytania z powodzeniem interpretuje się jako nazwy jednoczęściowe:

myproc - jednoczęściowy (bez cudzysłowów i ograniczników - punktor 1)
[myproc] - jednoczęściowy (w nawiasach - punktor 4)
„myproc” - jednoczęściowy (w cudzysłowie - punkt 2)
„dbo.myproc” - wieloczęściowy z wymaganymi pojedynczymi cudzysłowami
[dbo.myproc] - jednoczęściowy (w nawiasach - punktor 4)

Dwa ostatnie przykłady pytania są analizowane jako nazwy parametrów wieloczęściowych (ze względu na odsłonięty .separator). Powodują błąd, ponieważ brakuje wymaganych, obejmujących je pojedynczych cudzysłowów:

dbo.myproc - wieloczęściowy bez wymaganych pojedynczych znaków cudzysłowu
[dbo]. [myproc] - wieloczęściowy bez wymaganych pojedynczych znaków cudzysłowu

Ten dodatkowy przykład z użyciem podwójnych cudzysłowów jest udany:

„dbo.myproc” - jednoczęściowy (w cudzysłowie - punktator # 3)

Zauważ, że jest z powodzeniem interpretowany (dla wartości parametru procedury) jako poprawna nazwa pojedynczej części , ale kod procedury jest w stanie interpretować (wieloczęściowy) ciąg, który odbiera elastycznie (używając PARSENAMEi OBJECTID).

Jako ostatni punkt zainteresowania należy zauważyć, że użycie tutaj podwójnych cudzysłowów nie zależy od ustawienia QUOTED_IDENTIFIER.

Paul White 9
źródło