sp_describe_first_result_set (Transact-SQL)

Применимо к:SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure Управляемый экземпляр SQL Azure Конечная точка аналитики аналитики Synapse Analytics Analytics (PDW)SQL Analyticsв Microsoft FabricХранилище в Microsoft Fabric

Возвращает метаданные для первого возможного результирующий набор пакета Transact-SQL. Возвращает пустой результирующий набор, если пакет не вернул результатов. Вызывает ошибку, если ядро СУБД не может определить метаданные для первого запроса, который будет выполняться путем статического анализа. Динамическое представление управления sys.dm_exec_describe_first_result_set (Transact-SQL) возвращает те же сведения.

Соглашения о синтаксисе Transact-SQL

Синтаксис

  
sp_describe_first_result_set [ @tsql = ] N'Transact-SQL_batch'   
    [ , [ @params = ] N'parameters' ]   
    [ , [ @browse_information_mode = ] <tinyint> ] ]  

Аргументы

[ @tsql = ] 'Transact-SQL_batch' Одна или несколько инструкций Transact-SQL. Transact-SQL_batch может быть nvarchar(n) или nvarchar(max).

[ @params = ] N'parameters' @params предоставляет строку объявления для параметров пакета Transact-SQL, который аналогичен sp_executesql. Параметры могут быть nvarchar(n) или nvarchar(max).

Одна строка, содержащая определения всех параметров, внедренных в Transact-SQL_batch. Строка должна представлять собой константу в Юникоде либо переменную в этом же формате. Определение каждого параметра состоит из имени параметра и типа данных. n — это заполнитель, указывающий дополнительные определения параметров. Каждый параметр, указанный в инструкции, должен быть определен в @params. Если инструкция Transact-SQL или пакет в инструкции не содержит параметров, @params не требуется. Значением по умолчанию для этого аргумента является NULL.

[ @browse_information_mode = ] tinyint Указывает, возвращаются ли дополнительные ключевые столбцы и сведения о исходной таблице. Если он имеет значение 1, то каждый запрос анализируется аналогично анализу запроса с параметром FOR BROWSE. Возвращаются дополнительные ключевые столбцы и сведения об исходной таблице.

  • Если задано значение 0, то данные не возвращаются.

  • Если он имеет значение 1, то каждый запрос анализируется аналогично анализу запроса с параметром FOR BROWSE. Это приводит к возврату имен базовых таблиц в качестве сведений об исходном столбце.

  • Если задано значение 2, то каждый запрос анализируется так, как если бы он использовался для подготовки или выполнения курсора. Тогда в качестве сведений об исходном столбце возвращаются имена представлений.

Значения кода возврата

sp_describe_first_result_set всегда возвращает состояние нуля при успешном выполнении. Если процедура вызывает ошибку, а процедура вызывается как RPC, состояние возврата заполняется типом ошибки, описанной в столбце error_type sys.dm_exec_describe_first_result_set. Если процедура вызывается из Transact-SQL, возвращаемое значение всегда равно нулю, даже если возникает ошибка.

Результирующие наборы

Эти общие метаданные возвращаются в виде результирующего набора с одной строкой для каждого столбца в результирующих метаданных. Каждая строка описывает тип и допустимость значений NULL в столбце в формате, описанном в следующем разделе. Если первая инструкция не существует для каждого пути управления, возвращается результирующий набор с нулем строк.

Имя столбца Тип данных Description
is_hidden bit NOT NULL Указывает, что столбец является дополнительным, добавленным для целей просмотра сведений, и что он фактически не отображается в результирующем наборе.
column_ordinal int NOT NULL Содержит порядковый номер столбца в результирующем наборе. Позиция первого столбца будет указана как 1.
name sysname NULL Содержит имя столбца, если его можно определить. В противном случае будет содержать значение NULL.
is_nullable bit NOT NULL Содержит значение 1, если столбец допускает значения NULL, значение 0, если столбец не допускает значения NULL, и значение 1, если не удалось определить, допускает ли столбец значения NULL.
system_type_id int NOT NULL Содержит system_type_id типа данных столбца, указанного в sys.types. Для типов CLR, даже если system_type_name возвращает NULL, этот столбец вернет значение 240.
system_type_name nvarchar(256) NULL Содержит имя и аргументы (длина, точность, масштаб и т. д.), указанные для типа данных столбца. Если тип данных является пользовательским псевдонимом, то здесь указывается базовый системный тип данных. Если это определяемый пользователем тип данных CLR, то в этом столбце вернется NULL.
max_length smallint NOT NULL Максимальная длина столбца (в байтах).

-1 = типом данных столбца является varchar(max), nvarchar(max), varbinary(max) или xml.

Для текстовых столбцов значением max_length будет 16 или значение параметра "text in row", установленное процедурой sp_tableoption.
precision tinyint NOT NULL Точность столбца, если он является числовым. В противном случае возвращает 0.
scale tinyint NOT NULL Масштаб значений столбца в случае числового выражения. В противном случае возвращает 0.
collation_name sysname NULL Имя параметров сортировки столбца, если он символьный. В противном случае возвращается NULL.
user_type_id int NULL Для типов CLR и псевдонимов содержит user_type_id для типа данных столбца, как указано в sys.types. В противном случае значение равно NULL.
user_type_database sysname NULL Для типов CLR и псевдонимов содержит имя базы данных, в которой этот тип определен. В противном случае значение равно NULL.
user_type_schema sysname NULL Для типов CLR и псевдонимов содержит имя схемы, в которой этот тип определен. В противном случае значение равно NULL.
user_type_name sysname NULL Для типов CLR и псевдонимов содержит имя типа. В противном случае значение равно NULL.
assembly_qualified_type_name nvarchar(4000) Для типов CLR возвращает имя сборки и класса, определяющего тип. В противном случае значение равно NULL.
xml_collection_id int NULL Содержит xml_collection_id для типа данных столбца, как указано в sys.columns. Этот столбец возвратит NULL, если возвращаемый тип не связан с коллекцией схем XML.
xml_collection_database sysname NULL Содержит базу данных, в которой определена коллекция схем XML, связанная с этим типом. Этот столбец возвратит NULL, если возвращаемый тип не связан с коллекцией схем XML.
xml_collection_schema sysname NULL Содержит схему, в которой определена коллекция схем XML, связанная с этим типом. Этот столбец возвратит NULL, если возвращаемый тип не связан с коллекцией схем XML.
xml_collection_name sysname NULL Содержит имя коллекции схем XML, связанной с этим типом. Этот столбец возвратит NULL, если возвращаемый тип не связан с коллекцией схем XML.
is_xml_document bit NOT NULL Возвращает значение 1, если возвращается тип данных XML, который гарантированно будет полным XML-документом (включая корневой узел), а не фрагментом XML. В противном случае возвращает 0.
is_case_sensitive bit NOT NULL Возвращает значение 1, если столбец относится к строковому типу с учетом регистра, либо значение 0 в противном случае.
is_fixed_length_clr_type bit NOT NULL Возвращает значение 1, если столбец относится имеет тип CLR с фиксированной длиной, либо в противном случае значение 0.
source_server sysname Имя исходного сервера, возвращаемое столбцом этого результата (если он исходит от удаленного сервера). Имя присваивается, как оно отображается в sys.servers. Возвращает NULL, если столбец поступает с локального сервера или если невозможно определить, с какого сервера он поступил. Заполняется только при запросе просмотра информации.
source_database sysname Имя исходной базы данных, возвращаемое столбцом этого результата. Возвращает NULL, если не удалось определить базу данных. Заполняется только при запросе просмотра информации.
source_schema sysname Имя исходной схемы, возвращаемое столбцом в этом результате. Возвращает NULL, если не удалось определить схему. Заполняется только при запросе просмотра информации.
source_table sysname Имя исходной таблицы, возвращаемое столбцом в этом результате. Возвращает NULL, если не удалось определить таблицу. Заполняется только при запросе просмотра информации.
source_column sysname Имя исходного столбца, возвращаемое результирующим столбцом. Возвращает NULL, если не удалось определить столбец. Заполняется только при запросе просмотра информации.
is_identity_column битовое значение NULL Возвращает значение 1, если столбец является столбцом идентификаторов, либо значение 0 в противном случае. Возвращает NULL, если не удалось определить, является ли столбец столбцом идентификаторов.
is_part_of_unique_key битовое значение NULL Возвращает значение 1, если столбец является частью уникального индекса (включая ограничение уникальности и первичности), либо значение 0 в противном случае. Возвращает NULL, если не удалось определить, является ли столбец частью уникального индекса. Заполняется только при запросе просмотра информации.
is_updateable битовое значение NULL Возвращает значение 1, если столбец можно обновлять, либо значение 0 в противном случае. Возвращает NULL, если не удалось определить, можно ли обновлять столбец.
is_computed_column битовое значение NULL Возвращает значение 1, если столбец является вычисляемым столбцом, либо значение 0 в противном случае. Возвращает NULL, если не удалось определить, является ли столбец вычисляемым столбцом.
is_sparse_column_set битовое значение NULL Возвращает значение 1, если столбец является разреженным, и значение 0 в противном случае. Возвращает NULL, если не удалось определить, является ли столбец частью набора разреженных столбцов.
ordinal_in_order_by_list smallint NULL Позиция этого столбца в списке ORDER BY. Возвращает NULL, если столбец не отображается в списке ORDER BY, или если список ORDER BY нельзя однозначно определить.
order_by_list_length smallint NULL Длина списка ORDER BY. Возвращает NULL, если нет списка ORDER BY или если список ORDER BY нельзя однозначно определить. Обратите внимание, что это значение будет одинаковым для всех строк, возвращаемых sp_describe_first_result_set.
order_by_is_descending smallint NULL Если ordinal_in_order_by_list не равно NULL, столбец order_by_is_descending сообщает направление предложения ORDER BY для этого столбца. В противном случае возвращается значение NULL.
tds_type_id int NOT NULL Для внутреннего использования.
tds_length int NOT NULL Для внутреннего использования.
tds_collation_id int NULL Для внутреннего использования.
tds_collation_sort_id tinyint NULL Для внутреннего использования.

Замечания

sp_describe_first_result_set гарантирует, что если процедура возвращает первые метаданные результирующих наборов для (гипотетической) пакета А, а если этот пакет (A) будет выполнен, то пакет либо (1) вызывает ошибку времени оптимизации, то (2) вызывает ошибку времени выполнения, (3) не возвращает результирующий набор или (4) возвращает первый результирующий набор с теми же метаданными, описанными sp_describe_first_result_set.

Имя, допустимость значений NULL и тип данных могут различаться. Если sp_describe_first_result_set возвращает пустой результирующий набор, гарантируется, что выполнение пакета не возвращает результирующие наборы.

Эта гарантия предполагает отсутствие соответствующих изменений схемы на сервере. Соответствующие изменения схемы на сервере не включают создание временных таблиц или переменных таблицы в пакете A между вызовом sp_describe_first_result_set и временем возврата результирующий набор во время выполнения, включая изменения схемы, внесенные пакетом B.

sp_describe_first_result_set возвращает ошибку в любом из следующих случаев.

  • Если входной @tsql не является допустимым пакетом Transact-SQL. Допустимость определяется анализом и анализом пакета Transact-SQL. Любые ошибки, вызванные пакетом во время оптимизации запросов или во время выполнения, не учитываются при определении допустимости пакета Transact-SQL.

  • Если @params не имеет значения NULL и содержит строку, которая не является синтаксически допустимой строкой объявления для параметров или содержит строку, которая объявляет любой параметр несколько раз.

  • Если входной пакет Transact-SQL объявляет локальную переменную того же имени, что и параметр, объявленный в @params.

  • Если инструкция использует временную таблицу.

  • В запрос включено создание постоянной таблицы, к которой он будет обращен.

При успешном выполнении остальных проверок учитываются все возможные пути потоков управления. Это учитывает все инструкции потока управления (GOTO, IF/ELSE, WHILE и Transact-SQL TRY/CATCH), а также все процедуры, динамические пакеты Transact-SQL или триггеры, вызываемые из входного пакета инструкцией EXEC, инструкцией DDL, которая приводит к запуску триггеров DDL или инструкции DML, которая вызывает запуск триггеров DML в целевой таблице или в таблице, которая изменяется из-за каскадного действия внешнего ключа. Зависимости. При наличии нескольких возможных путей управления на определенном этапе выполнение алгоритма прерывается.

Для каждого пути потока управления первый оператор (при наличии), возвращающий результирующий набор, определяется sp_describe_first_result_set.

При наличии в пакете нескольких первых инструкций результаты могут различаться, т.е. могут быть получены различные количества столбцов, имена столбцов, допустимости значений NULL и типы данных. Ниже более подробно описывается обработка этих различий:

  • При получении различного количества столбцов в результатах вызывается ошибка и результат не возвращается.

  • Если отличаются имена столбцов, для имен возвращаемых столбцов задается значение NULL.

  • Если различается допустимость значений NULL, то будет разрешено задание значений NULL.

  • Если типы данных различаются, будет вызвана ошибка и не будет возвращен результат, за исключением следующих случаев:

    • varchar(a) для varchar(a'), где a ' > a.

    • varchar(a) для varchar(max)

    • nvarchar(a) в nvarchar(a') где a' > a.

    • nvarchar(a) до nvarchar(max)

    • varbinary(a) для varbinary(a') где a' > a.

    • varbinary(a) для varbinary(max)

sp_describe_first_result_set не поддерживает непрямую рекурсию.

Разрешения

Требуется разрешение на выполнение аргумента @tsql.

Примеры

Наиболее распространенные примеры

А. Простой пример

В следующем примере описывается результирующий набор, возвращаемый одним запросом.

sp_describe_first_result_set @tsql = N'SELECT object_id, name, type_desc FROM sys.indexes'  

В следующем примере описывается результирующий набор, возвращаемый одним запросом, в котором содержится параметр.

sp_describe_first_result_set @tsql =   
N'SELECT object_id, name, type_desc   
FROM sys.indexes   
WHERE object_id = @id1'  
, @params = N'@id1 int'  

B. Примеры режима просмотра

В следующих трех примерах показаны ключевые различия между разными режимами просмотра сведений. В результаты запроса включены только столбцы, относящиеся к теме.

В примере используется значение 0, которое указывает, что возврата сведений не происходит.

CREATE TABLE dbo.t (a int PRIMARY KEY, b1 int);  
GO  
CREATE VIEW dbo.v AS SELECT b1 AS b2 FROM dbo.t;  
GO  
EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM dbo.v', null, 0;  

Результирующий набор:

is_hidden column_ordinal name source_schema source_table source_column is_part_of_unique_key
0 1 b3 NULL NULL NULL NULL

В примере используется значение 1, которое указывает, что возврат сведений происходит так, как если бы в запросе был указан параметр FOR BROWSE.

EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM v', null, 1  
  

Результирующий набор:

is_hidden column_ordinal name source_schema source_table source_column is_part_of_unique_key
0 1 b3 dbo t B1 0
1 2 a dbo t a 1

В примере используется значение 2, которое показывает, что анализ выполняется так же, как и при подготовке курсора.

EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM v', null, 2  

Результирующий набор:

is_hidden column_ordinal name source_schema source_table source_column is_part_of_unique_key
0 1 B3 dbo v B2 0
1 2 ROWSTAT NULL NULL NULL 0

C. Хранение результатов в таблице

В некоторых сценариях необходимо поместить результаты sp_describe_first_result_set процедуры в некоторую таблицу, чтобы можно было дополнительно обработать схему. Сначала необходимо создать таблицу, которая соответствует выходным данным sp_describe_first_result_set процедуры:

create table #frs (
    is_hidden bit not null,
    column_ordinal int not null,
    name sysname null,
    is_nullable bit not null,
    system_type_id int not null,
    system_type_name nvarchar(256) null,
    max_length smallint not null,
    precision tinyint not null,
    scale tinyint not null,
    collation_name sysname null,
    user_type_id int null,
    user_type_database sysname null,
    user_type_schema sysname null,
    user_type_name sysname null,
    assembly_qualified_type_name nvarchar(4000),
    xml_collection_id int null,
    xml_collection_database sysname null,
    xml_collection_schema sysname null,
    xml_collection_name sysname null,
    is_xml_document bit not null,
    is_case_sensitive bit not null,
    is_fixed_length_clr_type bit not null,
    source_server sysname null,
    source_database sysname null,
    source_schema sysname null,
    source_table sysname null,
    source_column sysname null,
    is_identity_column bit null,
    is_part_of_unique_key bit null,
    is_updateable bit null,
    is_computed_column bit null,
    is_sparse_column_set bit null,
    ordinal_in_order_by_list smallint null,
    order_by_list_length smallint null,
    order_by_is_descending smallint null,
    tds_type_id int not null,
    tds_length int not null,
    tds_collation_id int null,
    tds_collation_sort_id tinyint null
);

При создании таблицы можно сохранить схему некоторых запросов в этой таблице.

declare @tsql nvarchar(max) = 'select top 0 * from sys.credentials';

insert #frs
exec sys.sp_describe_first_result_set @tsql;

select * from #frs;

Примеры проблем

Ниже во всех примерах используются две таблицы. Для создания примеров таблиц выполните следующие инструкции.

CREATE TABLE dbo.t1 (a int NULL, b varchar(10) NULL, c nvarchar(10) NULL);  
CREATE TABLE dbo.t2 (a smallint NOT NULL, d varchar(20) NOT NULL, e int NOT NULL);  

Ошибка, вызванная различием в количестве столбцов

В этом примере различается количество столбцов в возможных первых результирующих наборах.

sp_describe_first_result_set @tsql =   
N'  
IF(1=1)  
    SELECT a FROM t1;  
ELSE  
    SELECT a, b FROM t1;  
SELECT * FROM t; -- Ignored, not a possible first result set.'  
  

Ошибка, вызванная различием типов данных

Типы столбцов различаются в возможных первых результирующих наборах.

sp_describe_first_result_set @tsql =   
N'  
IF(1=1)  
    SELECT a FROM t1;  
ELSE  
    SELECT a FROM t2;  

Результат: ошибка, несоответствие типов (int и smallint).

Не удается определить имя столбца

У столбцов в различных первых результирующих наборах различается длина в одном типе переменной длины, допустимость значений NULL и имена столбцов:

sp_describe_first_result_set @tsql =   
N'  
IF(1=1)  
    SELECT b FROM t1;  
ELSE  
    SELECT d FROM t2; '  

Результат: <неизвестное имя>столбца varchar(20) NULL

Для имен столбцов принудительно обеспечивается соответствие с помощью присвоения псевдонимов

Аналогично предыдущему, но имена столбцов идентичны благодаря присвоению псевдонимов.

sp_describe_first_result_set @tsql =   
N'  
IF(1=1)  
    SELECT b FROM t1;  
ELSE  
    SELECT d AS b FROM t2;'  

Результат: b varchar(20)NULL

Ошибка, вызванная невозможностью сопоставления типов столбцов

Типы столбцов различаются в возможных первых результирующих наборах.

sp_describe_first_result_set @tsql =   
N'  
IF(1=1)  
    SELECT b FROM t1;  
ELSE  
    SELECT c FROM t1;'  

Результат: ошибка, несоответствие типов (varchar(10) и nvarchar(10)).

Результирующий набор может вернуть ошибку

Первым результирующим набором передается либо ошибка, либо действительно результирующий набор.

sp_describe_first_result_set @tsql =   
N'  
IF(1=1)  
    RAISERROR(''Some Error'', 16, 1);  
  
ELSE  
    SELECT a FROM t1;  
SELECT e FROM t2; -- Ignored, not a possible first result set.;'  

Результат: intNULL

Некоторые кодовые пути не возвращают результаты

Первым результирующим набором передается либо значение NULL, либо действительно результирующий набор.

sp_describe_first_result_set @tsql =   
N'  
IF(1=1)  
    RETURN;  
SELECT a FROM t1;'  

Результат: intNULL

Результат динамического SQL

Первый результирующий набор является динамическим SQL, который можно обнаружить, поскольку он является строковым литералом.

sp_describe_first_result_set @tsql =   
N'EXEC(N''SELECT a FROM t1'');'  

Результат: INT NULL

Результат: ошибка динамического SQL

Невозможно определить первый результирующий набор из-за динамического SQL.

sp_describe_first_result_set @tsql =   
N'  
DECLARE @SQL NVARCHAR(max);  
SET @SQL = N''SELECT a FROM t1 WHERE 1 = 1 '';  
IF(1=1)  
    SET @SQL += N'' AND e > 10 '';  
EXEC(@SQL); '  

Результат: ошибка. Результат невозможно обнаружить из-за динамического SQL.

Результирующий набор, указываемый пользователем

Первый результирующий набор указывается пользователем вручную.

sp_describe_first_result_set @tsql =   
N'  
DECLARE @SQL NVARCHAR(max);  
SET @SQL = N''SELECT a FROM t1 WHERE 1 = 1 '';  
IF(1=1)  
    SET @SQL += N'' AND e > 10 '';  
EXEC(@SQL)  
    WITH RESULT SETS(  
        (Column1 BIGINT NOT NULL)  
    ); '  

Результат: столбец1 bigint NOT NULL

Ошибка, вызванная неоднозначным результирующий набор

В этом примере предполагается, что другой пользователь с именем user1 содержит таблицу с именем t1 в схеме по умолчанию со столбцами (int NOT NULL).

sp_describe_first_result_set @tsql =   
N'  
    IF(@p > 0)  
    EXECUTE AS USER = ''user1'';  
    SELECT * FROM t1;'  
, @params = N'@p int'  

Результат: ошибка. t1 может быть dbo.t1 или s1.t1, каждый из которых имеет другое количество столбцов.

Результат возвращается даже при неоднозначном результирующем наборе

Используйте те же предположения, что и в предыдущем примере.

sp_describe_first_result_set @tsql =   
N'  
    IF(@p > 0)  
    EXECUTE AS USER = ''user1'';  
    SELECT a FROM t1;'  

Результат: int NULL, так как оба dbo.t1.a и s1.t1.a имеют тип int и разные значения NULL.

См. также

sp_describe_undeclared_parameters (Transact-SQL)
sys.dm_exec_describe_first_result_set (Transact-SQL)
sys.dm_exec_describe_first_result_set_for_object (Transact-SQL)