Бөлісу құралы:


sp_describe_first_result_set (Transact-SQL)

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

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

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

Синтаксис

sp_describe_first_result_set [ @tsql = ] N'tsql'
    [ , [ @params = ] N'@parameter_name data_type [ , ... n ]' ]
    [ , [ @browse_information_mode = ] <tinyint> ]
[ ; ]

Аргументы

[ @tsql = ] 'tsql'

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

[ @params = ] N'@parameter_name data_type [ , ... n ]'

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

Строка, содержащая определения всех параметров, внедренных в @tsql. Строка должна представлять собой константу в Юникоде либо переменную в этом же формате. Определение каждого параметра состоит из имени параметра и типа данных. 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 Указывает, что столбец является дополнительным столбцом, добавленным для целей просмотра сведений, и что он фактически не отображается в результирующем наборе. Не допускает значения NULL.
column_ordinal int Содержит порядковый номер столбца в результирующем наборе. Позиция первого столбца указывается как 1. Не допускает значения NULL.
name sysname Содержит имя столбца, если его можно определить. В противном случае он содержит NULL. Допускает значение NULL.
is_nullable bit Содержит значение1, если столбец разрешает, 0 если столбец не разрешаетNULLNULL, и 1 если он не может быть определен, разрешен ли столбецNULL. Не допускает значения NULL.
system_type_id int Содержит system_type_id тип данных столбца, как указано в sys.types. Для типов СРЕДЫ CLR, даже если system_type_name столбец возвращается NULL, этот столбец возвращает значение 240. Не допускает значения NULL.
system_type_name nvarchar(256) Содержит имя и аргументы (длина, точность, масштаб и т. д.), указанные для типа данных столбца. Если тип данных является пользовательским псевдонимом, то здесь указывается базовый системный тип данных. Если это определяемый пользователем тип СРЕДЫ CLR, NULL возвращается в этом столбце. Допускает значение NULL.
max_length smallint Максимальная длина столбца (в байтах).

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

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

Замечания

sp_describe_first_result_set гарантирует, что если процедура возвращает первые метаданные результирующих наборов для пакета A (гипотетической) и если этот пакет (A) будет выполнен, пакет либо:

  • Вызывает ошибку времени оптимизации
  • Вызывает ошибку во время выполнения
  • возвращает не результирующий набор
  • возвращает первый результирующий набор с теми же метаданными, которые описаны 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, , WHILEIFELSE/и блоки Transact-SQL), а также все процедуры, динамические пакеты Transact-SQL/TRYCATCH или триггеры, вызываемые из входного пакета EXEC инструкцией, инструкцией DDL, которая приводит к запуску триггеров DDL или инструкции DML, которая приводит к срабатыванию триггеров на целевой таблице или в таблице, которая изменяется из-за каскадного действия по ограничению внешнего ключа. В какой-то момент, как и во многих возможных путях управления, алгоритм останавливается.

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

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

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

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

  • Если значение NULL отличается, возвращается значение NULLNULL.

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

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

Примеры

Типичные примеры

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

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

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

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

EXEC 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 INTO #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
);

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

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

EXEC 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.';

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

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

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

Это приводит к ошибке несоответствия типов (int и smallint).

Невозможно определить имя столбца

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

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

Далее представлен частичный результирующий набор.

Столбец Значение
name Неизвестное имя столбца
system_type_name varchar
max_length 20
is_nullable 1

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

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

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

Далее представлен частичный результирующий набор.

Столбец Значение
name b
system_type_name varchar
max_length 20
is_nullable 1

Ошибка, так как типы столбцов не могут быть сопоставлены

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

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

Это приводит к ошибке несоответствия типов (varchar(10) и nvarchar(10)).

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

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

EXEC 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.';

Далее представлен частичный результирующий набор.

Столбец Значение
name a
system_type_name int
is_nullable 1

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

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

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

Далее представлен частичный результирующий набор.

Столбец Значение
name a
system_type_name int
is_nullable 1

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

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

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

Далее представлен частичный результирующий набор.

Столбец Значение
name a
system_type_name int
is_nullable 1

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

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

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

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

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

EXEC 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)
    );';

Далее представлен частичный результирующий набор.

Столбец Значение
name Column1
system_type_name bigint
is_nullable 0

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

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

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

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

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

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

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

Далее представлен частичный результирующий набор.

Столбец Значение
name a
system_type_name int
is_nullable 1

Оба dbo.t1.a типа и s1.t1.a тип int и разные значения NULL.