Soms, wanneer u een query uitvoert in SQL Server, wilt u misschien weten wat het onderliggende gegevenstype van elke kolom is, de precisie, lengte, of het nullable is, enz.
Als u slechts één tabel opvraagt, kunt u dit soort gegevens verkrijgen met procedures zoals sp_columns
. Maar als uw zoekopdracht over veel tabellen loopt, kan dit heel snel onpraktisch worden.
Gelukkig zijn er verschillende manieren om dergelijke metadata voor een resultaatset in SQL Server te verkrijgen.
De sp_describe_first_result_set
Door het systeem opgeslagen procedure
De sp_describe_first_result_set
systeem opgeslagen procedure is speciaal ontworpen voor het retourneren van de metagegevens voor een resultatenset.
Het accepteert drie parameters, maar de laatste twee zijn optioneel. De eerste parameter is de T-SQL-query die u wilt analyseren.
Hier is een voorbeeld van deze procedure in actie.
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;
Je kunt de query eigenlijk als een letterlijke tekenreeks opgeven, maar in dit geval heb ik hem in een variabele met de naam @tsql_query
geplaatst .
Resultaat:
+-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+---------------+--------------+--------------------+-------------------------+ | 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 | +-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+---------------+--------------+--------------------+-------------------------+
Zoals u kunt zien, retourneert deze opgeslagen procedure veel kolommen.
Als je goed kijkt naar de query die ik aan het analyseren ben, zul je merken dat een van de tabellen waarnaar wordt verwezen zich op een gekoppelde server met de naam "Homer" bevindt. In de resultaten geproduceerd door sp_describe_first_result_set
, de waarde in de source_server
kolom weerspiegelt deze gekoppelde server voor die onderliggende kolom.
In dit voorbeeld heb ik 1
. gebruikt als derde argument. Je kunt ook 0
. gebruiken of 2
. Zie hoe sp_describe_first_result_set
Werkt voor een uitleg en voorbeelden van hoe deze instelling de resultaten beïnvloedt.
De sys.dm_exec_describe_first_result_set
Systeemweergave
De sys.dm_exec_describe_first_result_set
systeemweergave gebruikt hetzelfde algoritme als sp_describe_first_result_set
, en het geeft dezelfde informatie terug.
Dus we kunnen ons vorige voorbeeld aanpassen om sys.dm_exec_describe_first_result_set
te gebruiken in plaats van 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
);
Resultaat:
+-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+ | 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 | +-------------+------------------+------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+
Net als bij sp_describe_first_result_set
, kunt u het tweede en derde argument wijzigen. Zie Hoe sys.dm_exec_describe_first_result_set werkt voor voorbeelden.
Gebruik OPENROWSET
Als je kijkt naar de broncode voor sys.dm_exec_describe_first_result_set
, zul je zien dat het OPENROWSET
. gebruikt om zijn resultaten te bereiken.
Op dezelfde manier kunnen we OPENROWSET
. gebruiken om iets soortgelijks te doen. We kunnen bijvoorbeeld OPENROWSET
. gebruiken om de top nul resultaten van een zoekopdracht in een tijdelijke tabel uit te voeren, gebruik dan de sp_columns
procedure om kolominformatie over die tijdelijke tabel te retourneren (die de resultatenset van onze zoekopdracht weerspiegelt).
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');
Resultaat:
+-------------------+---------------+----------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+-------------+-------------+----------+---------+---------+------------+-----------+--------------+-----------------+--------------------+---------------------+--------------------+---------------+----------------+ | 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 | +-------------------+---------------+----------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+-------------+-------------+----------+---------+---------+------------+-----------+--------------+-----------------+--------------------+---------------------+--------------------+---------------+----------------+
Je zou sp_columns
. kunnen vervangen met sp_help
indien gewenst.
Ik denk dat de eerste twee methoden beter zijn, maar het is in ieder geval een andere optie (vooral als je een oudere versie van SQL Server gebruikt die sys.dm_exec_describe_first_result_set
niet ondersteunt of sp_describe_first_result_set
.