DESCRIBE OUTPUT 语句

DESCRIBE OUTPUT 语句可获取有关所准备语句的信息。

有关预制语句的解释,请参阅 PREPARE语句

调用 DESCRIBE OUTPUT

此语句只能嵌入在应用程序中。 这是一个无法动态准备的可执行语句。 Java™中不能指定。

授权 DESCRIBE OUTPUT

如果为PREPARE设置的权限包括EXPLAIN权限,则可以执行该语句。

请参阅 PREPARE语句 ,了解创建预置语句所需的授权。

语法 DESCRIBE OUTPUT

阅读语法图跳过可视化语法图DESCRIBEOUTPUT声明-名称 INTO描述符名称USINGNAMESLABELSANYBOTH

描述 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×n3×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。

这种方法使用了大量的存储空间,这些存储空间永远不会被释放,即使大部分存储空间没有用于特定的选择列表也是如此。

第二种技术
对每个已处理的选定列表重复以下两个步骤:
  1. 使用没有SQLVAR的SQLDA执行DESCRIBE语句;也就是说,SQLN为零的SQLDA。
  2. 分配一个新的SQLDA,其中包含足够多的SQLVAR。 使用SQLD和SQLCODE返回的值来确定所需的SQLVAR条目数。 SQLD的值是结果表中的列数,它要么是SQLVAR所需出现的次数,要么是所需次数的一部分(详情请参阅确定需要多少SQLVAR出现次数 )。 如果SQLCODE为+236、+237、+238或+239,则所需的SQLVAR条目数量是SQLD中值的2到3倍,具体取决于是否指定了USING BOTH。 设置SQLN以反映已分配的SQLVAR条目数。
  3. 再次执行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 应该重置(如果需要)为 nn × 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

在 PL/I 程序中,使用不含 SQLVAR 的 SQLDA 执行 DESCRIBE 语句。 如果 SQLD 大于零,那么将使用该值来分配具有所需 SQLVAR 实例数的 SQLDA,然后使用该 SQLDA 执行 DESCRIBE 语句。
  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;
  .
  .
  .