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 если столбец не разрешаетNULL NULL , и 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
, , WHILE
IF
ELSE
/и блоки Transact-SQL), а также все процедуры, динамические пакеты Transact-SQL/TRY
CATCH
или триггеры, вызываемые из входного пакета EXEC
инструкцией, инструкцией DDL, которая приводит к запуску триггеров DDL или инструкции DML, которая приводит к срабатыванию триггеров на целевой таблице или в таблице, которая изменяется из-за каскадного действия по ограничению внешнего ключа. В какой-то момент, как и во многих возможных путях управления, алгоритм останавливается.
Для каждого пути потока управления первый оператор (при наличии), возвращающий результирующий набор, определяется sp_describe_first_result_set
.
При наличии в пакете нескольких первых инструкций результаты могут различаться, т.е. могут быть получены различные количества столбцов, имена столбцов, допустимости значений NULL и типы данных. Ниже более подробно описывается обработка этих различий:
При получении различного количества столбцов в результатах вызывается ошибка и результат не возвращается.
Если имя столбца отличается, возвращается
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 .
Примеры
Типичные примеры
А. Простой пример
В следующем примере описывается результирующий набор, возвращаемый одним запросом.
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 |
В. Хранение результатов в таблице
В некоторых сценариях необходимо поместить результаты 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.