À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
.