Ако някога се окажете в ситуация, в която ви предстои да изпълните съхранена процедура, но изведнъж се хванете. Чудите се „Колко колони връща това нещо? Кои маси? Запитва ли отдалечен сървър?”
Добрата новина е, че има няколко начина да получите тази информация, преди да стартирате заявката. Нека ги разгледаме.
sys.dm_exec_describe_first_result_set_for_object
Функция
Първата спирка е sys.dm_exec_describe_first_result_set_for_object
функция за динамично управление на системата.
Тази функция приема @object_id
като параметър и описва първите метаданни за резултата за модула с този идентификатор.
Може да се използва за съхранени процедури и тригери.
Ето пример за демонстрация. В този случай използвам OBJECT_ID()
функция за връщане на идентификатора на съхранената процедура (което ме спестява от необходимостта да знам действителния идентификатор).
SELECT *
FROM sys.dm_exec_describe_first_result_set_for_object(
OBJECT_ID('spAlbumsFromArtist'),
0
);
Резултат:
+-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+ | 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 | 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 | NULL | NULL | NULL | NULL | 0 | NULL | 1 | 0 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | | 0 | 2 | ReleaseDate | 0 | 40 | date | 3 | 10 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | NULL | NULL | NULL | NULL | NULL | 0 | NULL | 1 | 0 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | +-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+
Ако превъртите достатъчно настрани, ще видите, че source_server
, source_database
, source_schema
, source_table
и source_column
колоните са NULL
. Това е така, защото използвахме 0
като трети аргумент.
Превключване на третия аргумент към 1
ще върне информация за базовите таблици, посочени в съхранената процедура.
SELECT *
FROM sys.dm_exec_describe_first_result_set_for_object(
OBJECT_ID('spAlbumsFromArtist'),
1
);
Резултат:
+-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+ | 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 | 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 | Homer | Music | dbo | Albums | AlbumName | 0 | 0 | 1 | 0 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | | 0 | 2 | ReleaseDate | 0 | 40 | date | 3 | 10 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | Homer | Music | dbo | Albums | ReleaseDate | 0 | 0 | 1 | 0 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | | 1 | 3 | AlbumId | 0 | 56 | int | 4 | 10 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | Homer | Music | dbo | Albums | AlbumId | 0 | 1 | 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 | Homer | Music | dbo | Artists | ArtistId | 0 | 1 | 1 | 0 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | +-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+
Сега, когато превъртаме настрани, можем да видим, че source_server
, source_database
, source_schema
, source_table
и source_column
всички колони съдържат стойности.
В този случай процедурата прави заявки за таблици в свързан сървър, наречен „Homer“.
Ще забележите също, че вече има четири върнати реда, вместо само два, които бяха върнати, когато зададем третия аргумент на 0
. Двата допълнителни реда отразяват основните колони, които са заявени в рамките на съхранената процедура.
Ето дефиницията на съхранената процедура:
CREATE PROCEDURE [dbo].[spAlbumsFromArtist]
@ArtistName varchar(255)
AS
SELECT AlbumName, ReleaseDate
FROM Homer.Music.dbo.Albums al
INNER JOIN Homer.Music.dbo.Artists ar
ON al.ArtistId = ar.ArtistId
WHERE ar.ArtistName = @ArtistName;
Така че, въпреки че процедурата връща само две колони, тя трябва да препраща към други колони, за да изпълни задачата си.
Вижте как sys.dm_exec_describe_first_result_set_for_object
Работи за повече примери.
sys.dm_exec_describe_first_result_set
Преглед
Този изглед използва същия алгоритъм като предишния изглед и връща същата информация. Разликата е, че анализира T-SQL партида, а не действително съхранената процедура.
Това означава, че можете да използвате този изглед, за да анализирате код, който не е непременно в съхранена процедура или тригер. Например, можете да го използвате, за да анализирате изглед или ad hoc заявка.
Но тази статия е за анализиране на съхранени процедури, така че ето пример за това.
SELECT *
FROM sys.dm_exec_describe_first_result_set(
'EXEC spAlbumsFromArtist @ArtistId = ''Iron Maiden''',
null,
1
);
Резултат:
+-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+ | 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 | 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 | Homer | Music | dbo | Albums | AlbumName | 0 | 0 | 1 | 0 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | | 0 | 2 | ReleaseDate | 0 | 40 | date | 3 | 10 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | Homer | Music | dbo | Albums | ReleaseDate | 0 | 0 | 1 | 0 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | | 1 | 3 | AlbumId | 0 | 56 | int | 4 | 10 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | Homer | Music | dbo | Albums | AlbumId | 0 | 1 | 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 | Homer | Music | dbo | Artists | ArtistId | 0 | 1 | 1 | 0 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | +-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+
Вижте как sys.dm_exec_describe_first_result_set
Работи за повече примери.
Наборът sp_describe_first_result_set
Системна съхранена процедура
sp_describe_first_result_set
системната съхранена процедура прави същото (и използва същия алгоритъм). Той приема T-SQL пакет и връща метаданните за първия си възможен набор от резултати.
EXEC sp_describe_first_result_set
@tsql = N'EXEC spAlbumsFromArtist @ArtistId = ''Iron Maiden''',
@params = null,
@browse_information_mode = 1;
Резултат:
+-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+---------------+--------------+--------------------+-------------------------+ | 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 | 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 | Homer | Music | dbo | Albums | AlbumName | 0 | 0 | 1 | 0 | 0 | NULL | NULL | NULL | 231 | 510 | 13632521 | 52 | | 0 | 2 | ReleaseDate | 0 | 40 | date | 3 | 10 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | Homer | Music | dbo | Albums | ReleaseDate | 0 | 0 | 1 | 0 | 0 | NULL | NULL | NULL | 40 | 3 | NULL | NULL | | 1 | 3 | AlbumId | 0 | 56 | int | 4 | 10 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | Homer | Music | dbo | Albums | AlbumId | 0 | 1 | 1 | 0 | 0 | NULL | NULL | NULL | 56 | 4 | NULL | NULL | | 1 | 4 | ArtistId | 0 | 56 | int | 4 | 10 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | Homer | Music | dbo | Artists | ArtistId | 0 | 1 | 1 | 0 | 0 | NULL | NULL | NULL | 56 | 4 | NULL | NULL | +-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+---------------+--------------+--------------------+-------------------------+
Вижте как sp_describe_first_result_set
Работи за повече примери.
OPENROWSET
с временна таблица
Друга възможност е да се създаде заявка, която поставя горните нулеви резултати на OPENROWSET
запитвайте във временна таблица, след което използвайте процедура като sp_columns
за да върне информация за колона за тази временна таблица (която съдържа данните от нашия набор от резултати).
Следователно това ще предостави подробности, като имена на колони, типове данни и т.н.
SELECT TOP 0 * INTO #TempTable
FROM OPENROWSET(
'SQLNCLI',
'Server=localhost;Trusted_Connection=yes;',
'EXEC Test.dbo.sp_BadDogs');
EXEC('USE tempdb EXEC sp_columns #TempTable DROP TABLE #TempTable');
Резултат:
+-------------------+---------------+----------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+-------------+-------------+----------+---------+---------+------------+-----------+--------------+-----------------+--------------------+---------------------+--------------------+---------------+----------------+ | 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__________________________________________________________________________________________________________000000000017 | DogId | 4 | int | 10 | 4 | 0 | 10 | 0 | NULL | NULL | 4 | NULL | NULL | 1 | NO | 56 | | tempdb | dbo | #TempTable__________________________________________________________________________________________________________000000000017 | DogName | -9 | nvarchar | 255 | 510 | NULL | NULL | 1 | NULL | NULL | -9 | NULL | 510 | 2 | YES | 39 | | tempdb | dbo | #TempTable__________________________________________________________________________________________________________000000000017 | GoodDog | -7 | bit | 1 | 1 | NULL | NULL | 1 | NULL | NULL | -7 | NULL | NULL | 3 | YES | 50 | +-------------------+---------------+----------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+-------------+-------------+----------+---------+---------+------------+-----------+--------------+-----------------+--------------------+---------------------+--------------------+---------------+----------------+
Използвайки този метод, можете също да правите неща като размяна на sp_columns
за sp_help
или подобен.