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

3 maneiras de obter o esquema de um conjunto de resultados no SQL Server


Às vezes, quando você executa uma consulta no SQL Server, pode querer saber qual é o tipo de dados subjacente de cada coluna, sua precisão, comprimento, se é ou não anulável, etc.

Se você estiver consultando apenas uma tabela, poderá obter esse tipo de dados com procedimentos como sp_columns . Mas se sua consulta for executada em muitas tabelas, isso poderá se tornar complicado muito rapidamente.

Felizmente, existem várias maneiras de obter esses metadados para um conjunto de resultados no SQL Server.

O sp_describe_first_result_set Procedimento armazenado do sistema


O sp_describe_first_result_set procedimento armazenado do sistema foi projetado especificamente para retornar os metadados para um conjunto de resultados.

Ele aceita três parâmetros, mas os dois últimos são opcionais. O primeiro parâmetro é a consulta T-SQL que você deseja analisar.

Aqui está um exemplo deste procedimento em ação.
DECLARE @tsql_query nvarchar(max);
SET @tsql_query = 'SELECT
    ar.ArtistName,
    al.AlbumName,
    g.Genre
FROM 
    Artists ar 
    INNER JOIN Albums al 
    ON ar.ArtistId = al.ArtistId 
    INNER JOIN Homer.Music.dbo.Genres g 
    ON al.GenreId = g.GenreId';

EXEC sp_describe_first_result_set @tsql_query, null, 1;

Você pode realmente fornecer a consulta como uma string literal, mas neste caso eu a coloquei em uma variável chamada @tsql_query .

Resultado:
+-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+---------------+--------------+--------------------+-------------------------+
| is_hidden   | column_ordinal   | name       | is_nullable   | system_type_id   | system_type_name   | max_length   | precision   | scale   | collation_name               | user_type_id   | user_type_database   | user_type_schema   | user_type_name   | assembly_qualified_type_name   | xml_collection_id   | xml_collection_database   | xml_collection_schema   | xml_collection_name   | is_xml_document   | is_case_sensitive   | is_fixed_length_clr_type   | source_server   | source_database   | source_schema   | source_table   | source_column   | is_identity_column   | is_part_of_unique_key   | is_updateable   | is_computed_column   | is_sparse_column_set   | ordinal_in_order_by_list   | order_by_is_descending   | order_by_list_length   | tds_type_id   | tds_length   | tds_collation_id   | tds_collation_sort_id   |
|-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+---------------+--------------+--------------------+-------------------------|
| 0           | 1                | ArtistName | 0             | 231              | nvarchar(255)      | 510          | 0           | 0       | SQL_Latin1_General_CP1_CI_AS | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | NULL            | Music             | dbo             | Artists        | ArtistName      | 0                    | 0                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | 231           | 510          | 13632521           | 52                      |
| 0           | 2                | AlbumName  | 0             | 231              | nvarchar(255)      | 510          | 0           | 0       | SQL_Latin1_General_CP1_CI_AS | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | NULL            | Music             | dbo             | Albums         | AlbumName       | 0                    | 0                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | 231           | 510          | 13632521           | 52                      |
| 0           | 3                | Genre      | 0             | 231              | nvarchar(50)       | 100          | 0           | 0       | SQL_Latin1_General_CP1_CI_AS | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Genres         | Genre           | 0                    | 0                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | 231           | 100          | 13632521           | 52                      |
| 1           | 4                | ArtistId   | 0             | 56               | int                | 4            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | NULL            | Music             | dbo             | Artists        | ArtistId        | 1                    | 1                       | 0               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | 56            | 4            | NULL               | NULL                    |
| 1           | 5                | AlbumId    | 0             | 56               | int                | 4            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | NULL            | Music             | dbo             | Albums         | AlbumId         | 1                    | 1                       | 0               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | 56            | 4            | NULL               | NULL                    |
| 1           | 6                | GenreId    | 0             | 56               | int                | 4            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Genres         | GenreId         | 0                    | 1                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | 56            | 4            | NULL               | NULL                    |
+-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+---------------+--------------+--------------------+-------------------------+

Como você pode ver, esse procedimento armazenado retorna muitas colunas.

Se você observar atentamente a consulta que estou analisando, notará que uma das tabelas referenciadas está em um servidor vinculado chamado “Homer”. Nos resultados produzidos por sp_describe_first_result_set , o valor no source_server coluna reflete esse servidor vinculado para essa coluna subjacente.

Neste exemplo, usei 1 como terceiro argumento. Você também pode usar 0 ou 2 . Veja como sp_describe_first_result_set Funciona para uma explicação e exemplos de como essa configuração afeta os resultados.

O sys.dm_exec_describe_first_result_set Visualização do sistema


O sys.dm_exec_describe_first_result_set a visualização do sistema usa o mesmo algoritmo que sp_describe_first_result_set , e retorna as mesmas informações.

Assim, podemos modificar nosso exemplo anterior para usar sys.dm_exec_describe_first_result_set em vez de sp_describe_first_result_set .
DECLARE @tsql_query nvarchar(max);
SET @tsql_query = 'SELECT
    ar.ArtistName,
    al.AlbumName,
    g.Genre
FROM 
    Artists ar 
    INNER JOIN Albums al 
    ON ar.ArtistId = al.ArtistId 
    INNER JOIN Homer.Music.dbo.Genres g 
    ON al.GenreId = g.GenreId';
SELECT * 
FROM sys.dm_exec_describe_first_result_set(
    @tsql_query, 
    null, 
    1
    );

Resultado:
+-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+
| is_hidden   | column_ordinal   | name       | is_nullable   | system_type_id   | system_type_name   | max_length   | precision   | scale   | collation_name               | user_type_id   | user_type_database   | user_type_schema   | user_type_name   | assembly_qualified_type_name   | xml_collection_id   | xml_collection_database   | xml_collection_schema   | xml_collection_name   | is_xml_document   | is_case_sensitive   | is_fixed_length_clr_type   | source_server   | source_database   | source_schema   | source_table   | source_column   | is_identity_column   | is_part_of_unique_key   | is_updateable   | is_computed_column   | is_sparse_column_set   | ordinal_in_order_by_list   | order_by_is_descending   | order_by_list_length   | error_number   | error_severity   | error_state   | error_message   | error_type   | error_type_desc   |
|-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------|
| 0           | 1                | ArtistName | 0             | 231              | nvarchar(255)      | 510          | 0           | 0       | SQL_Latin1_General_CP1_CI_AS | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | NULL            | Music             | dbo             | Artists        | ArtistName      | 0                    | 0                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
| 0           | 2                | AlbumName  | 0             | 231              | nvarchar(255)      | 510          | 0           | 0       | SQL_Latin1_General_CP1_CI_AS | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | NULL            | Music             | dbo             | Albums         | AlbumName       | 0                    | 0                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
| 0           | 3                | Genre      | 0             | 231              | nvarchar(50)       | 100          | 0           | 0       | SQL_Latin1_General_CP1_CI_AS | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Genres         | Genre           | 0                    | 0                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
| 1           | 4                | ArtistId   | 0             | 56               | int                | 4            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | NULL            | Music             | dbo             | Artists        | ArtistId        | 1                    | 1                       | 0               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
| 1           | 5                | AlbumId    | 0             | 56               | int                | 4            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | NULL            | Music             | dbo             | Albums         | AlbumId         | 1                    | 1                       | 0               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
| 1           | 6                | GenreId    | 0             | 56               | int                | 4            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Genres         | GenreId         | 0                    | 1                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
+-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+

Assim como com sp_describe_first_result_set , você pode alterar o segundo e o terceiro argumentos. Consulte Como sys.dm_exec_describe_first_result_set funciona para obter exemplos.

Usando OPENROWSET


Se você observar o código-fonte de sys.dm_exec_describe_first_result_set , você verá que ele usa OPENROWSET para alcançar seus resultados.

Da mesma forma, podemos usar OPENROWSET fazer algo semelhante. Por exemplo, podemos usar OPENROWSET para executar os primeiros resultados zero de uma consulta em uma tabela temporária, use o sp_columns procedimento para retornar informações de coluna sobre essa tabela temporária (que reflete o conjunto de resultados de nossa consulta).
SELECT TOP 0 * INTO #TempTable 
FROM OPENROWSET(
    'SQLNCLI', 
    'Server=localhost;Trusted_Connection=yes;', 
    'SELECT
    ar.ArtistName,
    al.AlbumName,
    g.Genre
FROM 
    Music.dbo.Artists ar 
    INNER JOIN Music.dbo.Albums al 
    ON ar.ArtistId = al.ArtistId 
    INNER JOIN Music.dbo.Genres g 
    ON al.GenreId = g.GenreId');
EXEC('USE tempdb EXEC sp_columns #TempTable DROP TABLE #TempTable');

Resultado:
+-------------------+---------------+----------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+-------------+-------------+----------+---------+---------+------------+-----------+--------------+-----------------+--------------------+---------------------+--------------------+---------------+----------------+
| TABLE_QUALIFIER   | TABLE_OWNER   | TABLE_NAME                                                                                                                       | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | RADIX   | NULLABLE   | REMARKS   | COLUMN_DEF   | SQL_DATA_TYPE   | SQL_DATETIME_SUB   | CHAR_OCTET_LENGTH   | ORDINAL_POSITION   | IS_NULLABLE   | SS_DATA_TYPE   |
|-------------------+---------------+----------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+-------------+-------------+----------+---------+---------+------------+-----------+--------------+-----------------+--------------------+---------------------+--------------------+---------------+----------------|
| tempdb            | dbo           | #TempTable__________________________________________________________________________________________________________00000000000C | ArtistName    | -9          | nvarchar    | 255         | 510      | NULL    | NULL    | 0          | NULL      | NULL         | -9              | NULL               | 510                 | 1                  | NO            | 39             |
| tempdb            | dbo           | #TempTable__________________________________________________________________________________________________________00000000000C | AlbumName     | -9          | nvarchar    | 255         | 510      | NULL    | NULL    | 0          | NULL      | NULL         | -9              | NULL               | 510                 | 2                  | NO            | 39             |
| tempdb            | dbo           | #TempTable__________________________________________________________________________________________________________00000000000C | Genre         | -9          | nvarchar    | 50          | 100      | NULL    | NULL    | 0          | NULL      | NULL         | -9              | NULL               | 100                 | 3                  | NO            | 39             |
+-------------------+---------------+----------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+-------------+-------------+----------+---------+---------+------------+-----------+--------------+-----------------+--------------------+---------------------+--------------------+---------------+----------------+

Você pode substituir sp_columns com sp_help se preferir.

Acho que os dois primeiros métodos são melhores, mas pelo menos é outra opção (especialmente se você estiver usando uma versão mais antiga do SQL Server que não suporta sys.dm_exec_describe_first_result_set ou sp_describe_first_result_set .