sp_describe_first_result_set (Transact-SQL)

 

本主题适用于:是SQL Server(从 2012 开始)是Azure SQL 数据库否Azure SQL 数据仓库否并行数据仓库

返回的元数据的第一个可能的结果集的Transact-SQL批处理。 如果批处理没有返回结果,则返回一个空的结果集。 如果发出错误数据库引擎无法确定将由执行静态分析执行的第一个查询的元数据。 动态管理视图sys.dm_exec_describe_first_result_set (TRANSACT-SQL)返回相同的信息。

Topic link icon Transact-SQL 语法约定

适用范围: SQL Server (SQL Server 2012 到 当前版本)、 Azure SQL Database。
  
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。 字符串必须是 Unicode 常量或 Unicode 变量。 每个参数定义由参数名称和数据类型组成。 n是一个占位符,表示附加参数定义。 必须在定义语句中指定的每个参数@params。 如果Transact-SQL语句中的批处理不包含参数,@params不是必需的。 NULL 是此参数的默认值。

[ @browse_information_mode = ] tinyint
指定是否返回其他键列和源表信息。 如果设置为 1,则分析每个查询,就好像它在查询中包含 FOR BROWSE 选项一样。 将返回其他键列和源表信息。

  • 如果设置为 0,则无信息返回。

  • 如果设置为 1,则分析每个查询,就好像它在查询中包含 FOR BROWSE 选项一样。 该参数将返回用作源列信息的基表名称。

  • 如果设置为 2,则分析每个查询,就好像它用于准备或执行游标一样。 该参数将返回用作源列信息的视图名称。

sp_describe_first_result_set始终返回状态为成功的零。 如果该过程将引发错误,并且作为 RPC 调用该过程,则返回状态由 sys.dm_exec_describe_first_result_set error_type 列中所述的错误类型的填充。 如果从 Transact-SQL 中调用此过程,则返回值始终为零,甚至在出现错误时也不例外。

此公共元数据作为结果集返回,结果元数据中的每列对应于一行。 每一行以下面一节所说明的格式描述列的类型和为 Null 性。 如果对于每个控制路径不存在第一个语句,则返回的结果集不包含任何行。

列名数据类型Description
is_hidden位 NOT NULL指示列是出于浏览信息目的而额外添加的列,该列不会实际显示在结果集中。
column_ordinalint NOT NULL在结果集中包含列的序号位置。 第一列的位置将指定为 1。
名称sysname NULL包含列的名称(如果可以确定名称)。 否则,它将包含 NULL。
is_nullable位 NOT NULL如果列允许 NULL,则包含值 1;如果列不允许 NULL,则包含 0;如果不能确定列是否允许 NULL,则为 1。
system_type_idint NOT NULL包含 sys.types 中指定的列的数据类型的 system_type_id。 对于 CLR 类型,即使 system_type_name 列返回 NULL,该列也会返回值 240。
system_type_namenvarchar(256) NULL包含为列数据类型指定的名称和参数(例如,length、precision、scale)。 如果数据类型是用户定义的别名类型,则会在此处指定基本系统类型。 如果数据类型是 CLR 用户定义类型,则在此列中返回 NULL。
max_lengthsmallint 不为 NULL列的最大长度(字节)。

为-1 = 的列数据类型为varchar (max)nvarchar (max)varbinary (max),或xml

有关文本列, max_length值将为 16 或设置的值sp_tableoption 'text in row
精度tinyint 不为 NULL如果为基于数值的列,则为该列的精度。 否则,返回 0。
缩放tinyint 不为 NULL如果基于数值,则为列的小数位数。 否则,返回 0。
collation_namesysname NULL如果列包含的是字符,则为该列的排序规则的名称。 否则返回 NULL。
user_type_idint NULL对于 CLR 和别名类型,包含在 sys.types 中指定的列数据类型的 user_type_id。 否则为 NULL。
user_type_databasesysname NULL对于 CLR 和别名类型,包含在其中定义相应类型的数据库的名称。 否则为 NULL。
user_type_schemasysname NULL对于 CLR 和别名类型,包含在其中定义相应类型的架构的名称。 否则为 NULL。
user_type_namesysname NULL对于 CLR 和别名类型,包含类型的名称。 否则为 NULL。
assembly_qualified_type_namenvarchar (4000)对于 CLR 类型,返回定义类型的程序集和类的名称。 否则为 NULL。
xml_collection_idint NULL包含 sys.columns 中指定的列数据类型的 xml_collection_id。 如果返回的类型与 XML 架构集合不关联,则该列将返回 NULL。
xml_collection_databasesysname NULL包含定义与此类型关联的 XML 架构集合的数据库。 如果返回的类型与 XML 架构集合不关联,则该列将返回 NULL。
xml_collection_schemasysname NULL包含定义与此类型关联的 XML 架构集合的架构。 如果返回的类型与 XML 架构集合不关联,则该列将返回 NULL。
xml_collection_namesysname NULL包含与此类型关联的 XML 架构集合的名称。 如果返回的类型与 XML 架构集合不关联,则该列将返回 NULL。
is_xml_document位 NOT NULL如果返回的数据类型为 XML,并且保证该类型是完整的 XML 文档(包含根节点,与 XML 片段相对),则返回 1。 否则,返回 0。
is_case_sensitive位 NOT NULL如果列为区分大小写的字符串类型,则返回 1;否则为 0。
is_fixed_length_clr_type位 NOT NULL如果列为固定长度 CLR 类型,则返回 1;否则为 0。
source_serversysname此结果中的此列返回的源服务器的名称(如果结果源自远程服务器)。 在 sys.servers 中所示,未提供名称。 如果列来自本地服务器或无法确定它来自的服务器,则返回 NULL。 仅在请求浏览信息填充。
source_databasesysname此结果中的列返回的源数据库的名称。 如果无法确定该数据库,则返回 NULL。 仅在请求浏览信息填充。
source_schemasysname此结果中的列返回的源架构的名称。 如果无法确定该架构,则返回 NULL。 仅在请求浏览信息填充。
source_tablesysname此结果中的列返回的源表的名称。 如果无法确定该表,则返回 NULL。 仅在请求浏览信息填充。
source_columnsysname结果列返回的源列的名称。 如果无法确定该列,则返回 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_listsmallint NULL此列在 ORDER BY 列表中的位置。 如果 ORDER BY 列表中不显示该列或无法唯一确定 ORDER BY 列表,则返回 NULL。
order_by_list_lengthsmallint NULLORDER BY 列表的长度。 如果没有 ORDER BY 列表,或者无法唯一确定 ORDER BY 列表,则返回 NULL。 请注意,此值将是相同的返回的所有行sp_describe_first_result_set。
order_by_is_descendingsmallint NULL如果 ordinal_in_order_by_list 不为 NULL, order_by_is_descending列报告此列的 ORDER BY 子句的方向。 否则,它报告 NULL。
tds_type_idint NOT NULL供内部使用。
tds_lengthint NOT NULL供内部使用。
tds_collation_idint NULL供内部使用。
tds_collation_sort_idtinyint NULL供内部使用。

sp_describe_first_result_set保证,如果该过程返回 (一个假想) 的第一个结果集元数据批处理 A 和该批处理 (A) 是否随后执行然后批处理将任一 (1) 引发的优化时间错误、 (2) 引发运行时的错误、 (3) 返回任何结果集,或 (4) 返回的第一个结果集具有不同的元数据所描述sp_describe_first_result_set

名称、为 Null 性和数据类型可能不同。 如果sp_describe_first_result_set返回空结果集,保证是批处理执行将返回任何结果集。

此保证假定在服务器上没有相关的架构更改。 服务器上的相关的架构更改不包括创建临时表或表的时间之间的一个批次中的变量, 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,尽管,和Transact-SQLTRY/CATCH 块) 以及任何的过程中,动态Transact-SQL批处理或调用从输入批处理 EXEC 语句、 导致要激发的 DDL 触发器的 DDL 语句或 DML 语句目标表或修改由于级联操作上的外键约束的表上导致触发器激发的触发器。 在很多可能的控制路径的情况下,算法将在某个点停止。

对于每个控制流路径中,第一个语句 (如果有),返回的结果集由sp_describe_first_result_set

当在一个批处理中找到多个可能的第一个语句时,其结果可能在列数、列名称、为 Null 性以及数据类型等方面存在不同。 此处详细介绍了如何处理这些差异:

  • 如果列数不同,则会引发一个错误,但不返回任何结果。

  • 如果列名称不同,则返回的列名称将设置为 NULL。

  • 如果为 Null 性不同,则返回的为 Null 性将允许 NULL。

  • 如果数据类型不同,则将引发错误而不返回任何结果,但以下情况除外:

    • varchar(a)varchar(a')其中&1;>。

    • varchar(a)varchar (max)

    • nvarchar(a)nvarchar(a')其中&1;>。

    • nvarchar(a)nvarchar (max)

    • varbinary(a)varbinary(a')其中&1;>。

    • varbinary(a)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'  

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_hiddencolumn_ordinalnamesource_schemasource_tablesource_columnis_part_of_unique_key
01b3NULLNULLNULLNULL

以下示例使用 1,指示它将返回信息,就好像它在查询中包含 FOR BROWSE 选项一样。

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

下面是结果集:

is_hiddencolumn_ordinalnamesource_schemasource_tablesource_columnis_part_of_unique_key
01b3dbotB10
12(英文)。dbot(英文)。1

以下示例使用 2,指示执行分析,就好像您在准备游标一样。

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

下面是结果集:

is_hiddencolumn_ordinalnamesource_schemasource_tablesource_columnis_part_of_unique_key
01B3dbovB20
12ROWSTATNULLNULLNULL0

问题示例

下面的示例对所有示例使用两个表。 请执行以下语句以创建示例表。

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;  

结果︰ 错误,类型不匹配 (intsmallint)。

无法确定列名称

对于同一个变量长度类型、为 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)  
    ); '  

结果︰ Column1 bigint 不为 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;'  

结果︰ 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)

社区附加资源

添加
显示: