Parfois, lorsque vous exécutez une requête dans SQL Server, vous voudrez peut-être savoir quel est le type de données sous-jacent de chaque colonne, sa précision, sa longueur, si elle est nullable ou non, etc.
Si vous interrogez une seule table, vous pouvez obtenir ce type de données avec des procédures telles que sp_columns
. Mais si votre requête s'exécute sur de nombreuses tables, cela pourrait devenir très rapidement compliqué.
Heureusement, il existe plusieurs façons d'obtenir ces métadonnées pour un ensemble de résultats dans SQL Server.
Le sp_describe_first_result_set
Procédure stockée système
Le sp_describe_first_result_set
La procédure stockée système a été conçue spécifiquement pour renvoyer les métadonnées d'un ensemble de résultats.
Il accepte trois paramètres, mais les deux derniers sont facultatifs. Le premier paramètre est la requête T-SQL que vous souhaitez analyser.
Voici un exemple de cette procédure en action.
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;
Vous pouvez en fait fournir la requête sous forme de littéral de chaîne, mais dans ce cas, je l'ai placée dans une variable appelée @tsql_query
.
Résultat :
+-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+---------------+--------------+--------------------+-------------------------+ | 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 | +-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+---------------+--------------+--------------------+-------------------------+
Comme vous pouvez le voir, cette procédure stockée renvoie un grand nombre de colonnes.
Si vous regardez attentivement la requête que j'analyse, vous remarquerez que l'une des tables référencées se trouve sur un serveur lié appelé "Homer". Dans les résultats produits par sp_describe_first_result_set
, la valeur dans le source_server
colonne reflète ce serveur lié pour cette colonne sous-jacente.
Dans cet exemple, j'ai utilisé 1
comme troisième argument. Vous pouvez également utiliser 0
ou 2
. Voir comment sp_describe_first_result_set
Fonctionne pour une explication et des exemples de la façon dont ce paramètre affecte les résultats.
Le sys.dm_exec_describe_first_result_set
Vue système
Le sys.dm_exec_describe_first_result_set
la vue système utilise le même algorithme que sp_describe_first_result_set
, et il renvoie les mêmes informations.
Nous pouvons donc modifier notre exemple précédent pour utiliser sys.dm_exec_describe_first_result_set
au lieu 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
);
Résultat :
+-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+ | 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 | +-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+
Comme avec sp_describe_first_result_set
, vous pouvez modifier les deuxième et troisième arguments. Voir Fonctionnement de sys.dm_exec_describe_first_result_set pour des exemples.
Utilisation de OPENROWSET
Si vous regardez le code source de sys.dm_exec_describe_first_result_set
, vous verrez qu'il utilise OPENROWSET
pour atteindre ses résultats.
De même, nous pourrions utiliser OPENROWSET
faire une chose pareille. Par exemple, nous pourrions utiliser OPENROWSET
pour exécuter les premiers résultats zéro d'une requête dans une table temporaire, puis utilisez le sp_columns
procédure pour renvoyer des informations de colonne sur cette table temporaire (qui reflète le jeu de résultats de notre requête).
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');
Résultat :
+-------------------+---------------+----------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+-------------+-------------+----------+---------+---------+------------+-----------+--------------+-----------------+--------------------+---------------------+--------------------+---------------+----------------+ | 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 | +-------------------+---------------+----------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+-------------+-------------+----------+---------+---------+------------+-----------+--------------+-----------------+--------------------+---------------------+--------------------+---------------+----------------+
Vous pouvez remplacer sp_columns
avec sp_help
si préféré.
Je pense que les deux premières méthodes sont meilleures, mais au moins c'est une autre option (surtout si vous utilisez une ancienne version de SQL Server qui ne prend pas en charge sys.dm_exec_describe_first_result_set
ou sp_describe_first_result_set
.