DESCRIBE OUTPUT 语句
DESCRIBE OUTPUT 语句可获取有关所准备语句的信息。
有关预制语句的解释,请参阅 PREPARE语句。
调用 DESCRIBE OUTPUT
此语句只能嵌入在应用程序中。 这是一个无法动态准备的可执行语句。 Java™中不能指定。
授权 DESCRIBE OUTPUT
如果为PREPARE设置的权限包括EXPLAIN权限,则可以执行该语句。
请参阅 PREPARE语句 ,了解创建预置语句所需的授权。
语法 DESCRIBE OUTPUT
描述 DESCRIBE OUTPUT
- 输出
- 输出是一个可选关键字,用于指示描述语句返回有关准备好的SELECT语句中选择列表列的信息。
- statement-name
- 标识准备的语句。 当执行描述语句时,名称必须标识当前服务器上由应用程序进程准备的语句。 准备好的语句的结果表中的列不能是数组。
- INTO descriptor-name
- 标识一个SQL描述符区域(SQLDA),在 SQL描述符区域(SQLDA) 中进行了描述。 请参阅 《识别C或C++中的SQLDA 》,了解如何在C中表示描述符名称。对于REXX以外的语言 :在执行DESCRIBE语句之前,用户必须在SQLDA中设置以下变量,并且必须分配SQLDA。
- SQLN
- 指示 SQLDA 中提供的 SQLVAR 出现的次数。 Db2 不会改变这个值。 有关确定所需出现次数的技术,请参阅分配SQLDA。
对于REXX :SQLDA在使用前不会分配。 SQLDA由一组基本变量组成。 有一个可变词干.SQLD ,后面是零个或多个与SQLVAR结构等效的变量集。 这些变量以 stem.n。
在执行DESCRIBE OUTPUT语句后,SQLDA中除SQLN外的所有字段要么由 Db2 设置,要么被忽略。 有关字段内容的详细信息,请参阅 DESCRIBE OUTPUT返回的SQLDA内容。
- USING
- 指示为SQLDA中的每个SQLNAME变量分配什么值。 如果请求的值不存在,SQLNAME的长度将设置为0。
- 名称
- 指定列的名称。 这是缺省值。
- 标签
- 为列添加标签。 (列标签由LABEL语句定义。)
- 任何
为列添加标签。 如果列没有标签或标签是长度为0的字符串,则使用列名称。
- 资产和操作位置
- 指定列的标签和名称。 在这种情况下,每列需要出现两到三次SQLVAR,具体取决于结果集是否包含不同的类型,以容纳额外的信息。 为了指定SQLVAR数组的扩展,请将SQLN设置为 2×n 或 3×n ,其中 n 是所描述对象中的列数。 对于每个列,SQLVAR 的前n个出现 (即SQLVAR的基本条目)包含列名。 SQLVAR的第二个或第三个n次出现 (即扩展的SQLVAR条目)包含列标签。 如果没有明确的类型,则标签会返回到第二组SQLVAR条目中。 否则,标签将返回到第三组SQLVAR条目中。
备注 DESCRIBE OUTPUT
- 使用PREPARE INTO子句:
- 使用PREPARE语句中的INTO子句,也可以获取准备好的语句的相关信息。
- 分配SQLDA:
在执行DESCRIBE或PREPARE INTO语句之前,SQLN的值必须设置为大于或等于零的值,以指示SQLDA中SQLVAR的出现次数。 此外,必须分配足够的存储空间来容纳SQLN指定的事件数量。 要获取已准备好的 SELECT 语句结果表中的列描述,SQLVAR 的出现次数必须至少等于列的数量。 此外,如果指定了“同时使用”,或者列中包含LOB或不同类型,则SQLVAR的出现次数应为列数的两倍或三倍。 请参阅确定需要多少个SQLVAR出现以获取更多信息。
- 第一种技术
分配一个SQLDA,其中包含足够多的SQLVAR,以容纳应用程序需要处理的任何选择列表。 极端情况下,SQLVAR的数量可能达到结果表中允许的最大列数的3倍。 分配 SQLDA 后,应用程序可以重复使用 SQLDA。
这种方法使用了大量的存储空间,这些存储空间永远不会被释放,即使大部分存储空间没有用于特定的选择列表也是如此。
- 第二种技术
- 对每个已处理的选定列表重复以下两个步骤:
- 使用没有SQLVAR的SQLDA执行DESCRIBE语句;也就是说,SQLN为零的SQLDA。
- 分配一个新的SQLDA,其中包含足够多的SQLVAR。 使用SQLD和SQLCODE返回的值来确定所需的SQLVAR条目数。 SQLD的值是结果表中的列数,它要么是SQLVAR所需出现的次数,要么是所需次数的一部分(详情请参阅确定需要多少SQLVAR出现次数 )。 如果SQLCODE为+236、+237、+238或+239,则所需的SQLVAR条目数量是SQLD中值的2到3倍,具体取决于是否指定了USING BOTH。 设置SQLN以反映已分配的SQLVAR条目数。
- 再次执行DESCRIBE语句,u
与第一种技术相比,这种技术能够更好地管理存储,但DESCRIBE语句的数量增加了一倍。
唱新的SQLDA。
- 第三种技术
- 分配一个足够大但又不至于太大的SQLDA,以处理大多数(最好是全部)选择列表。 如果DESCRIBE语句因SQLDA太小而执行失败,请分配更大的SQLDA并再次执行DESCRIBE语句。
对于新的更大的SQLDA,使用失败DESCRIBE语句在SQLD和SQLCODE中返回的值来计算所需的SQLVAR的出现次数,如技术二所述。 请检查SQLCODEs +236、+237、+238和+239,它们指示是否需要扩展 SQLVAR条目,因为数据包含LOB或不同类型。
第三种技术是前两种技术的折中方案。 其有效性取决于对原始 SQLDA 大小的正确选择。
- DESCRIBE OUTPUT返回的SQLDA内容
在执行描述输出语句后,以下列表描述了SQLDA字段的设置内容,这些内容由 Db2 设置或忽略。
这些描述不一定适用于在其他SQL语句(EXECUTE、OPEN、FETCH)中使用SQLDA的情况。 有关其他用途的更多信息,请参阅 SQL描述符区(SQLDA )。
- SQLDAID
- Db2 将前6个字节设置为“SQLDA”(五个字母后跟空格字符),第七个字节设置为空格字符或一个数字,表示所需的SQLVAR条目数,第八个字节设置为空格字符。 SQLDAID的第七个字节可以设置为以下值,以指示描述结果表的每一列需要多少个SQLVAR条目:
- 空间
- 在以下情况下,SQLDAID的第七个字节为空格字符:
- 未指定使用“两者”,所描述的列不包括LOB或不同类型。 每列只需要一个SQLVAR条目。 如果SQL标准选项为是,则 Db2 会将SQLCODE设置为警告代码+236。 否则,SQLCODE为零。
- 指定使用“两者”,描述的列不包括LOB或不同类型。 每列需要两个SQLVAR条目。 Db2 将SQLD设置为结果表列数的两倍。 第二组SQLVAR用于标签。
- 2
- 每列需要两个SQLVAR条目。 在以下情况下,每列需要填写两个条目:
- 未指定同时使用,所描述的列包括LOB或不同类型或两者兼有。 Db2 设置第二组SQLVAR条目,其中包含描述的LOB或不同类型的信息。
- 指定使用“两者”,列包括LOB,但不包括不同类型。 Db2 设置第二组SQLVAR条目,其中包含LOB的信息和所描述列的标签。
- 3
- 每列需要三个SQLVAR条目。 仅当指定了“同时使用”且描述的列包含不同类型时,才需要填写三个条目。 LOB数据的存在并不重要。 当标签也被要求时,导致每列需要三个SQLVAR条目的原因是标签的类型不同,而不是LOB。 Db2 设置第二组SQLVAR条目,其中包含不同类型(以及LOB,如果有的话)的信息,设置第三组SQLVAR条目,其中包含所描述的列的标签。
有关如何使用SQLDAID的第七个字节的更多信息,请参阅确定需要多少个SQLVAR。
REXX SQLDA 不包含此字段。
- SQLDABC
- SQLDA的长度(以字节为单位)。 Db2 将值设置为 SQLN×44+16。
REXX SQLDA 不包含此字段。
- SQLD
- 如果准备好的语句是一个查询,则 Db2 会将值设置为被描述对象中的列数。
(对于REXX以外的语言,如果指定了“同时使用”,且结果表不包括LOB或不同类型,则该值实际上是列数的两倍。 对于REXX,如果指定了“同时使用”,则值是列数的两倍,无论结果表是否包含LOB或不同类型
否则,如果语句不是查询语句,则 会将该值设置为0。 Db2 - SQLVAR
- 正在描述的列的一系列字段描述信息。 SQLVAR条目有两种类型——基本SQLVAR和扩展SQLVAR。
如果SQLD的值为0或大于SQLN的值,则不会为SQLVAR的任何出现分配值。 如果SQLN的值设置得足够多,可以描述指定的列(带有LOB或不同类型的列,以及标签请求会增加所需的SQLVAR条目数量),则这些值将分配给 SQLVAR的前n个出现 ,以便SQLVAR的第一个出现包含第一个列的描述,第二个出现包含第二个列的描述,以此类推。 第一组SQLVAR条目被称为基本SQLVAR 条目。 每列总是有一个基本的SQLVAR条目。
如果描述语句包含使用两个子句,或者被描述的列包含LOB或不同类型,则需要额外的SQLVAR条目。 这些额外的SQLVAR条目被称为扩展SQLVAR条目。 每列最多可有两组扩展的SQLVAR条目。
对于 REXX,SQLVAR 是一组以 stem. n 开头的词干变量,而不是结构。 REXX SQLDA仅使用基本SQLVAR。
然而,REXX使用
。 Db2 为SQLVAR变量赋值的方式与其他语言相同。 也就是说, 变量stem.1 描述结果表的第一列, 变量stem.2 描述结果表的第二列,以此类推。 如果指定了 USING BOTH,则 stem +1 变量也描述结果表中的第一列, stem. n +2 变量也描述结果表中的第二列,依此类推。基本SQLVAR:- SQLTYPE
- 一个代码,用于指示列的数据类型以及列是否可以包含空值。 有关SQLTYPE的可能值,请参阅 SQLDA的SQLTYPE和SQLLEN字段。
- SQLLEN
- 长度值取决于结果列的数据类型。 对于LOB和XML数据类型,SQLLEN为0。 有关SQLLEN的其他可能值,请参阅 SQLDA的SQLTYPE和SQLLEN字段。
在REXX SQLDA中,对于DECIMAL或NUMERIC列, Db2 设置SQLPRECISION和SQLSCALE字段,而不是SQLLEN字段。
- SQLDATA
- 字符串列的CCSID。 可能的值请参见 SQLDA的SQLDATA字段。
在REXX SQLDA中, Db2 设置SQLCCSID字段,而不是SQLDATA字段。
- SQLIND
- 已保留。
- SQLNAME
- 根据 USING(NAMES、LABELS、ANY 或 BOTH)的值,列的无条件名称或标签。 如果列没有名称或标签,则字段为长度为0的字符串。 有关未命名列的详细信息,请参阅 select子句下有关结果列名称的讨论。 此值以包含语句的计划或包的编码绑定选项指定的编码方案返回。
SQLLONGL
仅对REXX而言,LOB列的长度属性。 其他语言在扩展的SQLVAR中使用SQLLONGLEN。
SQLCCSID
仅对REXX而言,LOB列的长度属性。
SQLTNAME
仅对于REXX,结果表中第n列的完全限定且不同的类型名称。 其他语言在扩展的SQLVAR中使用SQLDATATYPE-NAME。
扩展的SQLVAR:
- SQLLONGLEN
- BLOB、CLOB或DBCLOB列的长度属性。
- *
- 已保留。
- SQLDATALEN
- 未使用。
- sqldatatype-name
- 对于一种独特的类型,请使用全称独特的类型名称。 否则,该值是内置数据类型的完全限定名称。
对于专栏的标签。
此值以包含此语句的计划或包的编码绑定选项指定的编码方案返回。
- 性能考虑:
- 虽然 Db2 不会改变SQLN的值,但您可能希望在执行DESCRIBE语句后重新设置该值。 如果稍后的FETCH语句使用了DESCRIBE语句中的SQLDA内容,请在执行FETCH语句前将SQLN设置为 n (其中 n 是结果表的列数)。 详情请参阅 《为数据检索准备SQLDA 》
- 为数据检索准备SQLDA
如果您将 DESCRIBE 应用于已准备好的查询,并打算在检索结果表行的 FETCH 语句中使用 SQLDA,那么本说明与您有关。 为了准备SQLDA执行该任务,您必须设置SQLVAR的SQLDATA字段。 如果SQLTYPE为奇数,则必须设置SQLIND;如果覆盖CCSID,则必须设置SQLNAME。 关于这些字段在上下文中的含义,请参阅 SQL描述符区域(SQLDA )。
此外,SQLN 和 SQLDABC 应该重置(如果需要)为 n 和 n × 44+16,其中 n 是结果表中的列数。 当结果表的行被提取时,这样做可以提高性能。
- 支持分布式环境下的扩展动态 SQL:
在分布式环境中, Db2 for z/OS® 是服务器,请求者支持扩展动态 SQL,例如 Db2 server for VSE and VM ,针对扩展动态包中的 SQL 语句执行的 DESCRIBE 语句在 Db2 中看起来像是针对 Db2 包中的静态 SQL 语句执行的 DESCRIBE 语句。 通常情况下,静态SQL语句不能发出DESCRIBE语句。 然而,如果安装面板 DSNTIP4 上的“静态描述”字段设置为“是”,则在扩展动态SQL生成的静态SQL语句中执行描述时,如果包在安装面板上被重新绑定,则不会出现错误。
YES表示 Db2 在绑定时为DESCRIBE生成SQLDA,以便在执行时满足静态SQL语句的DESCRIBE请求。 更多信息,请参阅 “静态描述”字段(DESCSTAT子系统参数 )。
- 使用REOPT(ALWAYS)或REOPT(ONCE)时,避免重复准备:
如果绑定选项 REOPT(ALWAYS) 或 REOPT(ONCE) 生效,则 DESCRIBE 会导致语句在尚未准备好的情况下被准备。 如果DESCRIBE在OPEN或EXECUTE之前发出,则会导致语句在没有输入变量的情况下被准备。 如果语句有输入变量,则打开或执行时必须重新准备语句。 当REOPT(ONCE)生效时,即使没有输入变量,语句也会被准备两次。 因此,为避免重复准备语句,请在OPEN之后发布DESCRIBE。 对于非游标语句,在EXECUTE上执行打开和获取处理。 因此,如果必须出具描述性声明,则该声明将准备两次。
当预编译的语句指定了REOPT(ALWAYS)绑定选项,并且使用jcc驱动程序执行时,在EXPLAIN语句中使用预编译的语句可能会导致解释表中重复的条目。
- 描述中出现的错误:
- 在本地和远程处理中,DEFER(PREPARE)和REOPT(ALWAYS)/REOPT(ONCE)绑定选项可能会导致一些错误,这些错误通常在PREPARE处理期间发生,但在DESCRIBE期间发生。
- 隐含隐藏列的注意事项:
- 如果隐式隐藏的列(定义为隐式隐藏的基表的列)被明确指定为查询最终结果表的 SELECT 列表的一部分,则 DESCRIBED OUTPUT 语句仅返回有关隐式隐藏列的信息。 如果隐式隐藏列不是查询结果表的一部分,那么用于返回该查询相关信息的 DESCRIBE OUTPUT 语句不会包含有关任何隐式隐藏列的信息。
- 使用宿主变量:
- 如果 DESCRIBE 语句包含宿主变量,则宿主变量的内容将采用在绑定包含该语句的程序包或计划时在 ENCODING 参数中指定的编码方案。
- 数组元素注意事项:
- 当结果列对应于数组元素的引用,且该元素具有日期时间数据类型时,将返回 CCSID UNICODE。
示例 DESCRIBE OUTPUT
EXEC SQL BEGIN DECLARE SECTION;
DCL STMT1_STR CHAR(200) VARYING;
EXEC SQL END DECLARE SECTION;
EXEC SQL INCLUDE SQLDA;
EXEC SQL DECLARE DYN_CURSOR CURSOR FOR STMT1_NAME;
… /* code to prompt user for a query, then to generate */
/* a select-statement in the STMT1_STR */
EXEC SQL PREPARE STMT1_NAME FROM :STMT1_STR;
… /* code to set SQLN to zero and to allocate the SQLDA */
EXEC SQL DESCRIBE STMT1_NAME INTO :SQLDA;
… /* code to check that SQLD is greater than zero, to set */
/* SQLN to SQLD, then to re-allocate the SQLDA */
EXEC SQL DESCRIBE STMT1_NAME INTO :SQLDA;
… /* code to prepare for the use of the SQLDA */
EXEC SQL OPEN DYN_CURSOR;
… /* loop to fetch rows from result table */
EXEC SQL FETCH DYN_CURSOR USING DESCRIPTOR :SQLDA;
.
.
.