Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Abrufen der zugrunde liegenden Spalten einer Ansicht basierend auf ihrer Ergebnismenge

Eines der großartigen Dinge an Datenbankansichten ist, dass Sie damit komplexe Abfragen ausführen können, ohne das zugrunde liegende Datenbankschema kennen zu müssen.

Ja, es stimmt, dass Sie das zugrunde liegende Schema kennen müssen, wenn Sie die Ansicht erstellen, aber Sie müssen dies nur einmal tun. Sobald Sie sie erstellt haben, können Sie diese Ansicht den ganzen Tag lang abfragen, ohne sich alle Tabellen- und Spaltennamen usw. merken zu müssen.

Ansichten kombinieren typischerweise Daten aus mehreren Tabellen in einer einzigen, virtuellen Tabelle, was sie zu einer Art „Black Box“ macht. Solange es wie geplant funktioniert, brauchen Sie sich nicht um die versteckten Details zu kümmern.

Aber was, wenn Sie tun Möchten Sie eine Ansicht auf die zugrunde liegenden Tabellen und Spalten überprüfen?

Während die sp_help Die gespeicherte Systemprozedur liefert Ihnen Informationen zu den von der Ansicht zurückgegebenen Spalten, aber keine Informationen zu den Spalten in den Basistabellen, auf die in der Ansicht verwiesen wird.

Und ja, es gibt viele Möglichkeiten, die tatsächliche Definition der Ansicht zu überprüfen. Aber wenn es sich um eine große Ansicht handelt, laufen Sie Gefahr, zu schielen, wenn Sie nur versuchen, alle tatsächlich beteiligten Basistabellen herauszusuchen.

Es gibt jedoch eine andere Methode, mit der Sie die von einer Ansicht verwendeten Basistabellen und Spalten zurückgeben können.

Sie können das sys.dm_exec_describe_first_result_set verwenden dynamische Verwaltungsfunktion des Systems, um Metadaten über die Ergebnismenge zurückzugeben, wenn Sie die Ansicht abfragen.

So funktioniert es:Sie übergeben eine T-SQL-Abfrage an die Funktion und sie gibt Metadaten über die Ergebnismenge zurück. In diesem Fall wäre die Abfrage, die Sie an die Funktion übergeben, die Abfrage, die Sie beim Abfragen der Ansicht verwenden würden.

Ein Vorteil dieser Methode besteht darin, dass Sie die Basistabellen- und Spalteninformationen in einer übersichtlichen Liste erhalten. Jede Spalte wird in einer separaten Zeile aufgeführt.

Außerdem können Sie die Ergebnisse eingrenzen, indem Sie Ihre Abfrage verfeinern, was bedeutet, dass Sie alle irrelevanten Spalten entfernen können (d. h. Spalten, die in der Ansicht vorhanden sind, aber für Ihre spezifische Abfrage nicht relevant sind).

Beispiel

Hier ist ein Beispiel, um zu demonstrieren, wie es funktioniert.

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

Ergebnis:

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

Hier habe ich mich für die Verwendung von CONCAT() entschieden -Funktion, um mehrere Spaltennamen zu verketten, um die Visualisierung des Schemas zu vereinfachen.

In diesem Fall haben die Quellspalte und die Ansichtsspalte (d. h. die von der Ansicht zurückgegebene Spalte) beide denselben Namen. Dies geschieht, wenn die Ansicht keinen Alias ​​für die Spalte verwendet.

Beachten Sie, dass wir die Quellspalten, Tabellen usw. erhalten können, weil wir 1 verwenden als drittes Argument. Wenn wir diesen Wert verwenden, wird jede Abfrage so analysiert, als hätte sie einen FOR BROWSE Option in der Abfrage.

Wenn die Ansicht Spaltenaliase verwendet

Wenn die Ansicht Spaltenaliase verwendet, die sich von den tatsächlichen zugrunde liegenden Spaltennamen unterscheiden, spiegelt dies unsere Ergebnisse wider.

In diesem Beispiel fragen wir eine Ansicht ab, die Spaltenaliase verwendet.

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

Ergebnis:

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

Wenn wir uns die ersten beiden Zeilen ansehen, können wir sehen, dass die zugrunde liegenden Spalten (zurückgegeben von source_column Spalten) unterscheiden sich von der „Ansichtsspalte“ (zurückgegeben von name). Säule).

Wir können auch sehen, dass sich die Quellspalten für diese Ansicht auf einem Verbindungsserver namens „Homer“ befinden.

Eine weitere zu beachtende Sache ist, dass bei Verwendung des Browsermodus wie hier (d. h. mit 1 als drittes Argument) erhalten wir auch andere Spalten, die an der Vervollständigung der Abfrage beteiligt sind (ArtistId , AlbumId , und GenreId ), obwohl sie nicht wirklich in der Ergebnismenge zurückgegeben werden.

Verfeinern Sie die Abfrage

Eines der Dinge, die sys.dm_exec_describe_first_result_set unterscheiden von Prozeduren wie sp_help und sp_helptext , ist, dass es die Ergebnismenge beschreibt nicht die Aussicht.

Die Ergebnisse, die Sie erhalten, hängen von der tatsächlich übergebenen Abfrage ab, nicht nur von der Ansicht.

Hier ist die gleiche Abfrage wie im vorherigen Beispiel, außer dass ich dieses Mal nur eine Spalte aus der Ansicht auswähle (anstatt den * zu verwenden Platzhalter zum Auswählen aller Spalten).

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

Ergebnis:

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

Also werden diesmal nur vier statt sechs Zeilen zurückgegeben.

Rufen Sie die zugrunde liegenden Spalten aus mehreren Ansichten auf

Wie bereits erwähnt, das sys.dm_exec_describe_first_result_set -Funktion beschreibt die gesamte Ergebnismenge, nicht nur eine einzelne Ansicht oder ein anderes Objekt.

Daher können Sie die zugrunde liegenden Spalten aus mehreren Ansichten und Objekten auf einmal entdecken.

Beispiel:

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

Ergebnis:

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