En av de fantastiska sakerna med databasvyer är att de låter dig köra komplexa frågor utan att behöva känna till det underliggande databasschemat.
Ja, det är sant att du behöver känna till det underliggande schemat när du skapar vyn, men du behöver bara göra det en gång. När du har skapat den kan du fråga den vyn hela dagen utan att behöva komma ihåg alla tabell- och kolumnnamn osv.
Vyer kombinerar vanligtvis data från flera tabeller till en enda virtuell tabell, vilket gör det ungefär som en "svart låda". Så länge det fungerar som det är designat behöver du inte bry dig om de dolda detaljerna.
Men vad händer om du gör vill du kontrollera en vy för dess underliggande tabeller och kolumner?
Medan sp_help
Den systemlagrade proceduren ger dig information om kolumnerna som returneras av vyn, den ger inte information om kolumnerna i bastabellerna som refereras till i vyn.
Och ja, det finns många sätt att kontrollera den faktiska definitionen av vyn. Men om det är en stor vy, riskerar du att bli arg och bara försöka plocka ut alla faktiska bastabeller som är involverade.
Det finns dock en annan metod du kan använda för att returnera bastabellerna och kolumnerna som används av en vy.
Du kan använda sys.dm_exec_describe_first_result_set
dynamisk systemhanteringsfunktion för att returnera metadata om resultatuppsättningen när du frågar vyn.
Så det fungerar är att du skickar en T-SQL-fråga till funktionen, och den kommer att returnera metadata om resultatuppsättningen. I det här fallet skulle frågan som du skickar till funktionen vara den fråga du skulle använda när du frågade vyn.
En fördel med att använda den här metoden är att du får bastabellen och kolumninformationen i en snygg lista. Varje kolumn listas i en separat rad.
Du kan också begränsa resultaten genom att förfina din fråga, vilket innebär att du kan eliminera alla irrelevanta kolumner (dvs kolumner som finns i vyn, men som inte är relevanta för din specifika fråga).
Exempel
Här är ett exempel för att visa hur det fungerar.
SELECT
CONCAT(
source_server + '.',
source_database + '.',
source_schema + '.',
source_table + '.',
source_column) AS [Source Column],
name AS [View Column],
user_type_name,
system_type_name,
max_length,
[precision],
scale
FROM sys.dm_exec_describe_first_result_set(
N'SELECT * FROM vAllCats',
NULL,
1
);
Resultat:
+-----------------------+---------------+------------------+--------------------+--------------+-------------+---------+ | Source Column | View Column | user_type_name | system_type_name | max_length | precision | scale | |-----------------------+---------------+------------------+--------------------+--------------+-------------+---------| | Test.dbo.Cats.CatId | CatId | NULL | int | 4 | 10 | 0 | | Test.dbo.Cats.CatName | CatName | NULL | varchar(60) | 60 | 0 | 0 | +-----------------------+---------------+------------------+--------------------+--------------+-------------+---------+
Här har jag bestämt mig för att använda CONCAT()
funktion för att sammanfoga flera kolumnnamn för att göra det lättare att visualisera schemat.
I det här fallet har både källkolumnen och vykolumnen (dvs kolumnen som returneras av vyn) samma namn. Detta händer om vyn inte använder ett alias för kolumnen.
Observera att anledningen till att vi kan få källkolumner, tabeller, etc, är att vi använder 1
som det tredje argumentet. När vi använder det här värdet analyseras varje fråga som om den har en FOR BROWSE
alternativet på frågan.
När vyn använder kolumnalias
Om vyn använder kolumnalias som skiljer sig från de faktiska underliggande kolumnnamnen, kommer det att återspeglas våra resultat.
I det här exemplet frågar vi en vy som använder kolumnalias.
SELECT
CONCAT(
source_server + '.',
source_database + '.',
source_schema + '.',
source_table + '.',
source_column) AS [Source Column],
name AS [View Column],
user_type_name,
system_type_name,
max_length,
[precision],
scale
FROM sys.dm_exec_describe_first_result_set(
N'SELECT * FROM vAlbums',
NULL,
1
);
Resultat:
+------------------------------------+---------------+------------------+--------------------+--------------+-------------+---------+ | Source Column | View Column | user_type_name | system_type_name | max_length | precision | scale | |------------------------------------+---------------+------------------+--------------------+--------------+-------------+---------| | Homer.Music.dbo.Artists.ArtistName | Artist | NULL | nvarchar(255) | 510 | 0 | 0 | | Homer.Music.dbo.Albums.AlbumName | Album | NULL | nvarchar(255) | 510 | 0 | 0 | | Homer.Music.dbo.Genres.Genre | Genre | NULL | nvarchar(50) | 100 | 0 | 0 | | Homer.Music.dbo.Artists.ArtistId | ArtistId | NULL | int | 4 | 10 | 0 | | Homer.Music.dbo.Albums.AlbumId | AlbumId | NULL | int | 4 | 10 | 0 | | Homer.Music.dbo.Genres.GenreId | GenreId | NULL | int | 4 | 10 | 0 | +------------------------------------+---------------+------------------+--------------------+--------------+-------------+---------+
Om vi tittar på de två första raderna kan vi se att de underliggande kolumnerna (retureras av source_column
kolumner), skiljer sig från "Visa kolumn" (retureras av name
). kolumn).
Vi kan också se att källkolumnerna för denna vy finns på en länkad server som heter "Homer".
En annan sak att notera är att när du använder surfläge som vi är här (dvs. med 1
som det tredje argumentet) får vi även andra kolumner som är involverade i att slutföra frågan (ArtistId
, AlbumId
och GenreId
), även om de faktiskt inte returneras i resultatuppsättningen.
Förfina frågan
En av sakerna som skiljer sys.dm_exec_describe_first_result_set
åt från procedurer som sp_help
och sp_helptext
, är att den beskriver resultatuppsättningen inte utsikten.
Resultaten du får kommer att bero på den faktiska frågan du skickar, inte bara vyn.
Här är samma fråga som i föregående exempel, förutom att den här gången väljer jag bara en kolumn från vyn (istället för att använda *
jokertecken för att markera alla kolumner).
SELECT
CONCAT(
source_server + '.',
source_database + '.',
source_schema + '.',
source_table + '.',
source_column) AS [Source Column],
name AS [View Column],
user_type_name,
system_type_name,
max_length,
[precision],
scale
FROM sys.dm_exec_describe_first_result_set(
N'SELECT Album FROM vAlbums',
NULL,
1
);
Resultat:
+----------------------------------+---------------+------------------+--------------------+--------------+-------------+---------+ | Source Column | View Column | user_type_name | system_type_name | max_length | precision | scale | |----------------------------------+---------------+------------------+--------------------+--------------+-------------+---------| | Homer.Music.dbo.Albums.AlbumName | Album | NULL | nvarchar(255) | 510 | 0 | 0 | | Homer.Music.dbo.Artists.ArtistId | ArtistId | NULL | int | 4 | 10 | 0 | | Homer.Music.dbo.Albums.AlbumId | AlbumId | NULL | int | 4 | 10 | 0 | | Homer.Music.dbo.Genres.GenreId | GenreId | NULL | int | 4 | 10 | 0 | +----------------------------------+---------------+------------------+--------------------+--------------+-------------+---------+
Så den här gången returneras endast få fyra rader istället för sex.
Hämta de underliggande kolumnerna från flera vyer
Som nämnts, sys.dm_exec_describe_first_result_set
funktionen beskriver hela resultatuppsättningen, inte bara en enskild vy eller annat objekt.
Därför kan du upptäcka de underliggande kolumnerna från flera vyer och objekt på en gång.
Exempel:
SELECT
CONCAT(
source_server + '.',
source_database + '.',
source_schema + '.',
source_table + '.',
source_column) AS [Source Column],
name AS [View Column],
user_type_name,
system_type_name,
max_length,
[precision],
scale
FROM sys.dm_exec_describe_first_result_set(
N'SELECT * FROM vAllCats c INNER JOIN vAllDogs d ON c.CatName = d.DogName',
NULL,
1
);
Resultat:
+-----------------------+---------------+------------------+--------------------+--------------+-------------+---------+ | Source Column | View Column | user_type_name | system_type_name | max_length | precision | scale | |-----------------------+---------------+------------------+--------------------+--------------+-------------+---------| | Test.dbo.Cats.CatId | CatId | NULL | int | 4 | 10 | 0 | | Test.dbo.Cats.CatName | CatName | NULL | varchar(60) | 60 | 0 | 0 | | Test.dbo.Dogs.DogId | DogId | NULL | int | 4 | 10 | 0 | | Test.dbo.Dogs.DogName | DogName | NULL | nvarchar(255) | 510 | 0 | 0 | | Test.dbo.Dogs.GoodDog | GoodDog | NULL | bit | 1 | 1 | 0 | +-----------------------+---------------+------------------+--------------------+--------------+-------------+---------+