Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Obter as colunas subjacentes de uma exibição com base em seu conjunto de resultados


Uma das grandes vantagens das visualizações de banco de dados é que elas permitem que você execute consultas complexas sem a necessidade de conhecer o esquema de banco de dados subjacente.

Sim, é verdade que você precisa conhecer o esquema subjacente ao criar a exibição, mas só precisa fazer isso uma vez. Depois de criá-lo, você pode consultar essa visualização o dia todo sem precisar lembrar de todos os nomes de tabelas e colunas etc.

As visualizações geralmente combinam dados de várias tabelas em uma única tabela virtual, o que a torna uma espécie de “caixa preta”. Contanto que funcione como projetado, você não precisa se preocupar com os detalhes ocultos.

Mas e se você fazer deseja verificar uma exibição para suas tabelas e colunas subjacentes?

Enquanto o sp_help O procedimento armazenado do sistema fornecerá informações sobre as colunas retornadas pela exibição, não fornece informações sobre as colunas nas tabelas base referenciadas na exibição.

E sim, há muitas maneiras de verificar a definição real da visualização. Mas se for uma visão ampla, você corre o risco de ficar vesgo, apenas tentando escolher todas as tabelas básicas reais envolvidas.

No entanto, há outro método que você pode usar para retornar as tabelas e colunas base usadas por uma exibição.

Você pode usar o sys.dm_exec_describe_first_result_set função de gerenciamento dinâmico do sistema para retornar metadados sobre o conjunto de resultados quando você consulta a exibição.

A maneira como funciona é que você passa uma consulta T-SQL para a função e ela retornará metadados sobre o conjunto de resultados. Nesse caso, a consulta que você passa para a função seria a consulta que você usaria ao consultar a exibição.

Um benefício de usar esse método é que você obtém as informações da tabela base e da coluna em uma boa lista. Cada coluna é listada em uma linha separada.

Além disso, você pode restringir os resultados refinando sua consulta, o que significa que você pode eliminar quaisquer colunas irrelevantes (ou seja, colunas que estão na visualização, mas não são relevantes para sua consulta específica).

Exemplo


Aqui está um exemplo para demonstrar como funciona.
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
);

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

Aqui, decidi usar o CONCAT() função para concatenar vários nomes de coluna para facilitar a visualização do esquema.

Nesse caso, a Coluna de Origem e a Coluna de Visualização” (ou seja, a coluna retornada pela visualização) compartilham o mesmo nome. Isso acontecerá se a exibição não usar um alias para a coluna.

Observe que a razão pela qual podemos obter as colunas, tabelas, etc. de origem é porque usamos 1 como terceiro argumento. Quando usamos este valor, cada consulta é analisada como se tivesse um FOR BROWSE opção na consulta.

Quando a visualização usa alias de coluna


Se a exibição usar aliases de coluna diferentes dos nomes de coluna subjacentes reais, isso será refletido em nossos resultados.

Neste exemplo, consultamos uma exibição que usa aliases de coluna.
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
);

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

Se olharmos para as duas primeiras linhas, podemos ver que as colunas subjacentes (retornadas pelo source_column colunas), são diferentes de “View Column” (retornado pelo name coluna).

Também podemos ver que as colunas de origem para esta visão estão localizadas em um servidor vinculado chamado “Homer”.

Outra coisa a notar é que ao usar o modo de navegação como estamos aqui (ou seja, com 1 como terceiro argumento), também obtemos outras colunas envolvidas no preenchimento da consulta (ArtistId , AlbumId e GenreId ), mesmo que eles não sejam realmente retornados no conjunto de resultados.

Refinar a consulta


Uma das coisas que diferencia sys.dm_exec_describe_first_result_set de procedimentos como sp_help e sp_helptext , é que descreve o conjunto de resultados não a vista.

Os resultados obtidos dependerão da consulta real que você passar, não apenas da visualização.

Aqui está a mesma consulta do exemplo anterior, exceto que desta vez eu seleciono apenas uma coluna da visualização (em vez de usar o * curinga para selecionar todas as colunas).
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
);

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

Portanto, desta vez, apenas quatro linhas são retornadas em vez de seis.

Obter as colunas subjacentes de várias visualizações


Conforme mencionado, o sys.dm_exec_describe_first_result_set A função descreve todo o conjunto de resultados, não apenas uma única visualização ou outro objeto.

Portanto, você pode descobrir as colunas subjacentes de várias exibições e objetos de uma só vez.

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

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