sp_describe_first_result_set (Transact-SQL)
Возвращает метаданные для первого возможного результирующего набора пакета Transact-SQL. Возвращает пустой результирующий набор, если пакет не вернул результатов. Вызывает ошибку, если компоненту Компонент Database Engine не удается определить метаданные для первого запроса, который будет выполнен при выполнении статического анализа. Динамическое административное представление 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 всегда возвращает состояние 0 в случае успешной отправки. Если эта процедура вызывает ошибку и вызывается через RPC, то возвращаемое состояние заполняется типом ошибки, описанным в столбце error_type sys.dm_exec_describe_first_result_set. Если процедура вызывается из Transact-SQL, то возвращаемое значение всегда равно нулю, даже при наличии ошибок.
Результирующие наборы
Эти общие метаданные возвращаются в виде результирующего набора с одной строкой для каждого столбца в результирующих метаданных. Каждая строка описывает тип и допустимость значений NULL в столбце в формате, описанном в следующем разделе. Если первая инструкция не существует для каждого пути управления, возвращается результирующий набор с нулем строк.
Имя столбца |
Тип данных |
Описание |
---|---|---|
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. Для столбцов типа text значение max_length будет равно 16 или значению, заданному хранимой процедурой sp_tableoption 'text in row'. |
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 |
bit NULL |
Возвращает значение 1, если столбец является столбцом идентификаторов, либо значение 0 в противном случае. Возвращает NULL, если не удалось определить, является ли столбец столбцом идентификаторов. |
is_part_of_unique_key |
bit NULL |
Возвращает значение 1, если столбец является частью уникального индекса (включая ограничение уникальности и первичности), либо значение 0 в противном случае. Возвращает NULL, если не удалось определить, является ли столбец частью уникального индекса. Заполняется только при запросе просмотра информации. |
is_updateable |
bit NULL |
Возвращает значение 1, если столбец можно обновлять, либо значение 0 в противном случае. Возвращает NULL, если не удалось определить, можно ли обновлять столбец. |
is_computed_column |
bit NULL |
Возвращает значение 1, если столбец является вычисляемым столбцом, либо значение 0 в противном случае. Возвращает NULL, если не удалось определить, является ли столбец вычисляемым столбцом. |
is_sparse_column_set |
bit 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 и последующем выполнении этого пакета (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, вызывающая выполнение триггеров для целевой таблицы или таблицы, измененной при выполнении каскадного действия с ограничением внешнего ключа. При наличии нескольких возможных путей управления на определенном этапе выполнение алгоритма прерывается.
Для всех путей потоков управления первая инструкция (если есть), возвращающая результирующий набор, определяется sp_describe_first_result_set.
При наличии в пакете нескольких первых инструкций результаты могут различаться, т.е. могут быть получены различные количества столбцов, имена столбцов, допустимости значений NULL и типы данных. Ниже более подробно описывается обработка этих различий:
При получении различного количества столбцов в результатах вызывается ошибка и результат не возвращается.
Если отличаются имена столбцов, для имен возвращаемых столбцов задается значение NULL.
Если различается допустимость значений NULL, то будет разрешено задание значений NULL.
Если типы данных различаются, будет вызвана ошибка и не будет возвращен результат, за исключением следующих случаев:
varchar(a) в varchar(a'), где a' > a.
varchar(a) to varchar(max)
nvarchar(a) в nvarchar(a'), где a' > a.
nvarchar(a) to nvarchar(max)
varbinary(a) в varbinary(a'), где a' > a.
varbinary(a) to varbinary(max)
sp_describe_first_result_set не поддерживает косвенную рекурсию.
Разрешения
Требуется разрешение на выполнение аргумента @tsql.
Примеры
Наиболее распространенные примеры
A.Простой пример
В следующем примере описывается результирующий набор, возвращаемый одним запросом.
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'
Б.Примеры режима просмотра
В следующих трех примерах показаны ключевые различия между разными режимами просмотра сведений. В результаты запроса включены только столбцы, относящиеся к теме.
В примере используется значение 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 |
Примеры проблем
Ниже во всех примерах используются две таблицы. Для создания примеров таблиц выполните следующие инструкции.
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.;'
Результат: int NULL
Некоторые кодовые пути не возвращают результаты
Первым результирующим набором передается либо значение NULL, либо действительно результирующий набор.
sp_describe_first_result_set @tsql =
N'
IF(1=1)
RETURN;
SELECT a FROM t1;'
Результат: int NULL
Результат динамического SQL
Первый результирующий набор является динамическим SQL, который можно обнаружить, поскольку он является строковым литералом.
sp_describe_first_result_set @tsql =
N'EXEC(N''SELECT a FROM t1'');'
Результат: a 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 в схеме по умолчанию s1 со столбцами (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;'
Результат: a 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)