sql >> Databasteknik >  >> RDS >> Sqlserver

Få de underliggande kolumnerna i en vy baserat på dess resultatuppsättning

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


  1. Undvik detta vanliga fel när du kör lagrad procedur i MS Access

  2. Navigera i SQL Server-felloggar

  3. XML-prestandatips

  4. SQLite-undantag vid försök att ta bort rad