Jedną z największych zalet widoków bazy danych jest to, że umożliwiają uruchamianie złożonych zapytań bez konieczności znajomości bazowego schematu bazy danych.
Tak, to prawda, że podczas tworzenia widoku musisz znać podstawowy schemat, ale wystarczy to zrobić tylko raz. Po utworzeniu możesz wysyłać zapytania do tego widoku przez cały dzień bez konieczności zapamiętywania wszystkich nazw tabel i kolumn itp.
Widoki zazwyczaj łączą dane z wielu tabel w jedną wirtualną tabelę, co sprawia, że jest to trochę jak „czarna skrzynka”. Dopóki działa zgodnie z założeniami, nie musisz martwić się ukrytymi szczegółami.
Ale co, jeśli zrobisz chcesz sprawdzić widok pod kątem leżących u jego podstaw tabel i kolumn?
Podczas gdy sp_help
systemowa procedura składowana dostarczy informacji o kolumnach zwracanych przez widok, nie dostarcza informacji o kolumnach w tabelach bazowych, do których odwołuje się widok.
I tak, jest wiele sposobów na sprawdzenie rzeczywistej definicji widoku. Ale jeśli jest to duży widok, ryzykujesz zezowacenie oczu, próbując po prostu wybrać wszystkie rzeczywiste tabele bazowe.
Istnieje jednak inna metoda, której można użyć do zwrócenia tabel podstawowych i kolumn używanych przez widok.
Możesz użyć sys.dm_exec_describe_first_result_set
funkcja dynamicznego zarządzania systemem, która zwraca metadane dotyczące zestawu wyników podczas zapytania o widok.
Działa to tak, że przekazujesz zapytanie T-SQL do funkcji, która zwróci metadane dotyczące zestawu wyników. W takim przypadku zapytanie, które przekazujesz do funkcji, będzie zapytaniem, którego użyjesz podczas wysyłania zapytań do widoku.
Jedną z zalet korzystania z tej metody jest to, że otrzymujesz informacje o tabeli podstawowej i kolumnach w postaci ładnej listy. Każda kolumna jest wymieniona w osobnym wierszu.
Możesz także zawęzić wyniki, doprecyzowując zapytanie, co oznacza, że możesz wyeliminować wszelkie nieistotne kolumny (tj. kolumny, które są w widoku, ale nie są istotne dla konkretnego zapytania).
Przykład
Oto przykład pokazujący, jak to działa.
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
);
Wynik:
+-----------------------+---------------+------------------+--------------------+--------------+-------------+---------+ | 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 | +-----------------------+---------------+------------------+--------------------+--------------+-------------+---------+
Tutaj zdecydowałem się użyć CONCAT()
funkcja łączenia wielu nazw kolumn w celu ułatwienia wizualizacji schematu.
W tym przypadku kolumna źródłowa i kolumna widoku” (tj. kolumna zwrócona przez widok) mają tę samą nazwę. Stanie się tak, jeśli widok nie użyje aliasu dla kolumny.
Zauważ, że powodem, dla którego możemy uzyskać kolumny źródłowe, tabele itp., jest to, że używamy 1
jako trzeci argument. Kiedy używamy tej wartości, każde zapytanie jest analizowane tak, jakby miało FOR BROWSE
opcja w zapytaniu.
Gdy widok używa aliasów kolumn
Jeśli widok używa aliasów kolumn, które różnią się od rzeczywistych nazw kolumn, zostaną one odzwierciedlone w naszych wynikach.
W tym przykładzie wysyłamy zapytanie do widoku, który używa aliasów kolumn.
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
);
Wynik:
+------------------------------------+---------------+------------------+--------------------+--------------+-------------+---------+ | 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 | +------------------------------------+---------------+------------------+--------------------+--------------+-------------+---------+
Jeśli spojrzymy na pierwsze dwa wiersze, zobaczymy, że podstawowe kolumny (zwracane przez source_column
kolumn) różnią się od „Wyświetl kolumnę” (zwracaną przez name
kolumna).
Widzimy również, że kolumny źródłowe dla tego widoku znajdują się na połączonym serwerze o nazwie „Homer”.
Inną rzeczą, na którą należy zwrócić uwagę, jest to, że podczas korzystania z trybu przeglądania, takiego jak my tutaj (tj. z 1
jako trzeci argument) otrzymujemy również inne kolumny, które są zaangażowane w wypełnianie zapytania (ArtistId
, AlbumId
i GenreId
), mimo że w rzeczywistości nie są zwracane w zestawie wyników.
Doprecyzuj zapytanie
Jedna z rzeczy, które odróżniają sys.dm_exec_describe_first_result_set
z procedur takich jak sp_help
i sp_helptext
jest to, że opisuje zestaw wyników nie widok.
Otrzymane wyniki będą zależeć od faktycznie przekazanego zapytania, a nie tylko od widoku.
Oto to samo zapytanie, co w poprzednim przykładzie, ale tym razem wybieram tylko jedną kolumnę z widoku (zamiast używać *
symbol wieloznaczny, aby wybrać wszystkie kolumny).
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
);
Wynik:
+----------------------------------+---------------+------------------+--------------------+--------------+-------------+---------+ | 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 | +----------------------------------+---------------+------------------+--------------------+--------------+-------------+---------+
Tak więc tym razem zwracane są tylko cztery wiersze zamiast sześciu.
Pobierz podstawowe kolumny z wielu widoków
Jak wspomniano, sys.dm_exec_describe_first_result_set
funkcja opisuje cały zestaw wyników, a nie tylko pojedynczy widok lub inny obiekt.
Dlatego możesz odkryć leżące poniżej kolumny z wielu widoków i obiektów za jednym razem.
Przykład:
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
);
Wynik:
+-----------------------+---------------+------------------+--------------------+--------------+-------------+---------+ | 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 | +-----------------------+---------------+------------------+--------------------+--------------+-------------+---------+