SQLDA(SQL 描述符区域)

SQLDA 是执行 SQL DESCRIBE 语句所需的变量集合。

SQLDA 变量是可供 PREPARE , OPEN , FETCH 和 EXECUTE 语句使用的选项。 SQLDA 与动态 SQL 通信; 它可以在 DESCRIBE 语句中使用,使用主变量的地址进行修改,然后在 FETCH 或 EXECUTE 语句中复用。

SQL数据分析(SQLDA)支持所有语言,但仅为C、REXX、FORTRAN和 COBOL 提供预定义声明。

SQLDA 中信息的含义取决于其用途。 在 PREPARE 和 DESCRIBE 中, SQLDA 向应用程序提供有关预编译语句的信息。 在 OPEN , EXECUTE 和 FETCH 中, SQLDA 描述主变量。

在 DESCRIBE 和 PREPARE 中,如果要描述的任何列是 LOB 类型 (LOB 定位器和文件引用变量不需要加倍 SQLDA) ,引用类型或用户定义的类型,那么整个 SQLDA 的 SQLVAR 条目数将加倍。 例如:
  • 使用 3 VARCHAR 列和 1 INTEGER 列描述表时,将有 4 个 SQLVAR 条目
  • 使用 2 VARCHAR 列, 1 CLOB 列和 1 整数列描述表时,将有 8 个 SQLVAR 条目

在 EXECUTE , FETCH 和 OPEN 中,如果要描述的任何一个变量是 LOB 类型 (LOB 定位器和文件引用变量不需要加倍的 SQLDA) 或结构化类型,那么整个 SQLDA 的 SQLVAR 条目数必须加倍。 (单值类型和引用类型在这些情况下不相关,因为数据库不需要双精度值条目中的其他信息。 数组,游标和行类型在 EXECUTE , FETCH 和 OPEN 语句中不支持作为 SQLDA 变量。)

SQLDA 字段描述

SQLDA 由四个变量组成,后跟任意数目的出现变量序列 (统称为 SQLVAR)。 在 OPEN , FETCH 和 EXECUTE 中,每次出现 SQLVAR 都描述一个主变量。 在 DESCRIBE 和 PREPARE 中,每次出现 SQLVAR 都会描述结果表或参数标记的列。 有两种类型的 SQLVAR 条目:
  • 基本 SQLVARs: 这些条目始终存在。 它们包含有关列,参数标记或主变量的基本信息,例如数据类型代码,长度属性,列名,主变量地址和指示符变量地址。
  • 辅助 SQLVARs: 仅当根据先前概述的规则将 SQLVAR 条目数加倍时,才存在这些条目。 对于用户定义的类型 (不包括引用类型) ,它们包含用户定义的类型名称。 对于引用类型,它们包含引用的目标类型。 对于 LOB ,它们包含主变量的 length 属性以及指向包含实际长度的缓冲区的指针。 (单值类型和 LOB 信息不重叠,因此单值类型可以基于 LOB ,而不必强制将 DESCRIBE 上的 SQLVAR 条目数增加两倍。) 如果使用定位器或文件引用变量来表示 LOB ,那么不需要这些条目。
在包含这两种类型的条目的 SQLDA 中,基本 SQLVARs 位于辅助 SQLVARs 块之前的块中。 在每个条目中,条目数等于 SQLD 中的值 (即使许多辅助 SQLVAR 条目可能未使用)。

DESCRIBE 对 SQLDA 的影响中详细描述了由 DESCRIBE 设置 SQLVAR 条目的情况。

SQLDA 头中的字段

表 1. SQLDA 头中的字段
C 名称 SQL 数据类型 DESCRIBE 和 PREPARE 中的用法 (由数据库管理器设置, SQLN 除外) FETCH , OPEN 和 EXECUTE 中的用法 (在执行语句之前由应用程序设置)
SQLDAID CHAR(8) 此字段的第七个字节是名为SQL一番的标志字节。 如果为每个列创建了两个 SQLVAR 条目,那么数据库管理器会将SQL一番设置为字符 2 ; 否则设置为空白 (ASCII 中的X'20 ' , EBCDIC 中的 X'40' )。 请参阅 DESCRIBE 对 SQLDA 的影响 ,以获取有关何时设置SQL一番的详细信息。 当SQLVAR数目加倍时,将使用此字段的第七个字节。 它名为SQL一番。 如果所描述的任何主变量是结构化类型 BLOB , CLOB 或 DBCLOB ,那么第七个字节必须设置为字符 2; 否则可以设置为任何字符,但建议使用空白。
SQLDABC INTEGER 对于 32 位, SQLDA 的长度,等于 SQLN*44+16。 对于 64 位, SQLDA 的长度,等于 SQLN*56+16 对于 32 位, SQLDA 的长度> = 到 SQLN*44+16。 对于 64 位, SQLDA 的长度> = SQLN*56+16。
SQLN SMALLINT 未由数据库管理器更改。 在执行 DESCRIBE 语句之前,必须设置为大于或等于零的值。 指示 SQLVAR 的出现总数。 SQLDA 中提供的 SQLVAR 的出现总数。 SQLN 必须设置为大于或等于零的值。
SQLD SMALLINT 由数据库管理器设置为结果表中的列数或参数标记数。 由 SQLVAR 实例描述的主变量数。

基本 SQLVAR 实例中的字段

表 2. 基本 SQLVAR 中的字段
姓名 数据类型 DESCRIBE 和 PREPARE 中的用法 FETCH , OPEN 和 EXECUTE 中的用法
SQLTYPE SMALLINT 指示列或参数标记的数据类型,以及它是否可以包含空值。 (参数标记始终被视为可空。) 表 4 列出了允许的值及其含义。

请注意,对于不同的,数组,光标,行 或引用类型,基本类型的数据类型将放入此字段中。 对于结构化类型,将该类型的变换组的 FROM SQL 变换函数 (基于 CURRENT DEFAULT TRANSFORM GROUP 专用寄存器) 的结果的数据类型放入此字段中。 基本 SQLVAR 中没有指示它是用户定义的类型或引用类型的描述的一部分。

对于主变量相同。 日期时间值的主变量必须是字符串变量。 对于 FETCH ,日期时间类型代码表示固定长度的字符串。 如果 sqltype 是偶数值,那么将忽略 sqlind 字段。
SQLLEN SMALLINT 列或参数标记的长度属性。 对于日期时间列和参数标记,值的字符串表示的长度。 请参阅 表 4

请注意,对于大对象字符串,该值设置为 0 (即使对于其长度属性足够小以适合两个字节整数的对象字符串)。

主变量的长度属性。 请参阅 表 4

请注意, CLOB , DBCLOB 和 BLOB 列的数据库管理器将忽略该值。 改为使用辅助 SQLVAR 中的 len.sqllonglen 字段。

SQLDATA 指针 对于字符串 SQLVARS , sqldata 包含代码页。 对于使用 FOR BIT DATA 属性定义列的字符串 SQLVARs , sqldata 包含 0。 对于其他字符串 SQLVARS , sqldata 包含 SBCS 数据的 SBCS 代码页或与 MBCS 数据的组合 MBCS 代码页相关联的 SBCS 代码页。 对于日语 EUC ,繁体中文 EUC 和 Unicode UTF-8 字符串 SQLVARS , sqldata 分别包含 954,964 和 1208。

对于所有其他列类型,未定义 sqldata。

包含主变量的地址 (将在其中存储访存的数据)。
SQLIND 指针 对于字符串 SQLVARS ,当 sqlind 包含与组合 MBCS 代码页相关联的 DBCS 代码页时, sqlind 包含 0 (MBCS 数据除外)。

对于所有其他类型,未定义 sqlind。

包含关联指示符变量的地址 (如果有); 否则,不使用。 如果 sqltype 是偶数值,那么将忽略 sqlind 字段。
SQLNAME VARCHAR (30) 包含列或参数标记的非限定名。

对于具有系统生成的名称的列和参数标记,第 30 个字节设置为 X'FF '。 对于 AS 子句指定的列名,此字节为 X'00 '

连接到主机数据库时,可以设置 sqlname 以指示 FOR BIT DATA 字符串,如下所示:
  • SQLDA 头中 SQLDAID 的第六个字节设置为 +
  • sqlname 的长度为 8
  • sqlname 的前两个字节为 X'0000 '
  • sqlname 的第三个和第四个字节是 X'0000 '
  • 剩余的四个字节的 sqlname 是保留的,应该设置为 X'00000000 '
使用 XML 数据时,可以设置 sqlname 以指示 XML 子类型,如下所示:
  • sqlname 的长度为 8
  • sqlname 的前两个字节为 X'0000 '
  • sqlname 的第三个和第四个字节是 X'0000 '
  • sqlname 的第五个字节为 X'01 '
  • 其余三个字节的 sqlname 是保留的,应该设置为 X'000000 '

出现辅助 SQLVAR 时的字段

表 3. 辅助 SQLVAR 中的字段
姓名 数据类型 DESCRIBE 和 PREPARE 中的用法 FETCH , OPEN 和 EXECUTE 中的用法
len.sqllonglen INTEGER BLOB , CLOB 或 DBCLOB 列或参数标记的长度属性。 BLOB , CLOB 或 DBCLOB 主变量的长度属性。 数据库管理器将忽略数据类型的基本 SQLVAR 中的 SQLLEN 字段。 length 属性存储 BLOB 或 CLOB 的字节数以及 DBCLOB 的双字节字符数。
reserve2 CHAR (3) 表示 32 位, CHAR (11) 表示 64 位。 未使用。 未使用。
sqlflag4 CHAR(1) 如果 SQLVAR 表示具有 sqldatatype_name 中指定的目标类型的引用类型,那么值为 X'01 '。 如果 SQLVAR 表示结构化类型 (在 sqldatatype_name 中使用用户定义的类型名称) ,那么值为 X'12 '。 否则,值为 X'00 '。 如果 SQLVAR 表示具有 sqldatatype_name 中指定的目标类型的引用类型,请设置为 X'01 '。 如果 SQLVAR 表示结构化类型 (在 sqldatatype_name 中具有用户定义的类型名称) ,请设置为 X'12 '。 否则,值为 X'00 '。
sqldatalen 指针 未使用。 仅用于 BLOB , CLOB 和 DBCLOB 主变量。

如果此字段为空值,那么实际长度 (以双字节字符计) 应存储在数据开始之前的 4 字节中,并且 SQLDATA 应指向字段长度的第一个字节。

如果此字段不是空值,那么它将包含指向 4 字节长缓冲区的指针,该缓冲区包含从匹配基本 SQLVAR 中的 SQLDATA 字段指向的缓冲区中数据的实际长度 (以字节计) (即使对于 DBCLOB)。

请注意,无论是否使用此字段,都必须设置 len.sqllonglen 字段。

SQLDATATYPE_NAME VARCHAR(27) 对于用户定义的类型,数据库管理器将此类型设置为标准用户定义的类型名称。1 对于引用类型,数据库管理器将此设置为引用的目标类型的标准类型名称。 对于结构化类型,请按表说明中指示的格式设置为用户定义的标准类型名称。1
已保留 CHAR(3) 未使用。 未使用。
1 前 8 个字节包含类型的模式名称 (必要时使用空格扩展至右侧)。 字节 9 包含点 (.)。 字节 10 到 27 包含类型名称的低阶部分, 使用空格向右侧扩展。
请注意,尽管此字段的主要用途是用于用户定义类型的名称,但此字段也是针对 IBM® 预定义数据类型设置的。 在这种情况下,模式名称是 SYSIBM ,而名称的低阶部分是存储在 DATATYPES 目录视图的 TYPENAME 列中的名称。 例如:
type name        length   sqldatatype_name
---------        ------   ----------------
A.B              10       A       .B
INTEGER          16       SYSIBM  .INTEGER
"Frank's".SMINT  13       Frank's .SMINT
MY."type  "      15       MY      .type

DESCRIBE 对 SQLDA 的影响

对于 DESCRIBE OUTPUT 或 PREPARE OUTPUT INTO 语句,数据库管理器始终将 SQLD 设置为结果集中的列数或输出参数标记数。 对于 DESCRIBE INPUT 或 PREPARE INPUT INTO 语句,数据库管理器始终将 SQLD 设置为语句中的输入参数标记数。 请注意,在输入描述符和输出描述符中都描述了与 CALL 语句中的 INOUT 参数对应的参数标记。

在下列情况下,会设置 SQLDA 中的 SQLVARs:
  • SQLN> = SQLD ,没有条目是 LOB ,用户定义的类型或引用类型

    设置前 SQLD 个 SQLVAR 条目,并将 SQLDOUBLED 设置为空。

  • SQLN> = 2*SQLD ,并且至少有一个条目是 LOB ,用户定义的类型或引用类型

    设置了两次 SQLD SQLVAR 条目,并且SQL一番设置为 2

  • SQLD <= SQLN < 2*SQLD and at least one entry is a distinct,数组,光标,行, or reference type, but there are no LOB entries or structured type entries

    设置前 SQLD 个 SQLVAR 条目,并将 SQLDOUBLED 设置为空。 如果 SQLWARN 绑定选项是 YES,那么将发出警告 SQLCODE +237(SQLSTATE 01594)。

在下列情况下,不会设置 SQLDA 中的 SQLVARs (需要分配额外空间和另一个 DESCRIBE):
  • SQLN < SQLD 且该条目既非大对象(LOB)、用户自定义类型,亦非引用类型

    不设置任何 SQLVAR 条目,并将 SQLDOUBLED 设置为空。 如果 SQLWARN 绑定选项是 YES,那么将发出警告 SQLCODE +236(SQLSTATE 01005)。

    为成功的 DESCRIBE 分配 SQLD SQLVARs。

  • SQLN < SQLD and at least one entry is a distinct,数组,光标,行, or reference type, but there are no LOB entries or structured type entries

    不设置任何 SQLVAR 条目,并将 SQLDOUBLED 设置为空。 如果 SQLWARN 绑定选项是 YES,那么将发出警告 SQLCODE +239(SQLSTATE 01005)。

    为成功的 DESCRIBE 分配 2*SQLD SQLVARs ,包括不同的,数组,游标和行 类型以及引用类型的目标类型的名称。

  • SQLN < 2*SQLD 且至少有一条记录是大型对象(LOB)或结构化类型

    不设置任何 SQLVAR 条目,并将 SQLDOUBLED 设置为空。 发出警告 SQLCODE +238(SQLSTATE 01005),而不考虑 SQLWARN 绑定选项的设置。

    为成功的 DESCRIBE 分配 2*SQLD SQLVARs。

先前列表中对 LOB 条目的引用包括其源类型为 LOB 类型的单值类型条目。

BIND 或 PREP 命令的 SQLWARN 选项用于控制 DESCRIBE (或 PREPARE INTO) 是否将返回警告 SQLCODE + 236 , + 237 , + 239。 建议应用程序代码始终认为可以返回这些 SQLCODE。 当选择列表中存在 LOB 或结构化类型条目并且 SQLDA 中没有足够的 SQLVARs 时,将始终返回警告 SQLCODE +238。 这是应用程序知道由于结果集中的 LOB 或结构化类型条目而必须加倍 SQLVARs 数的唯一方法。

如果正在描述结构化类型条目,但未定义 FROM SQL 变换 (因为未使用 CURRENT DEFAULT TRANSFORM GROUP 专用寄存器指定 TRANSFORM GROUP (SQLSTATE 42741) 或由于名称组未定义 FROM SQL 变换函数 (SQLSTATE 42744)) ,那么 DESCRIBE 将返回错误。 对于具有结构化类型条目的表的 DESCRIBE ,此错误与返回的错误相同。

如果数据库管理器返回的标识比可存储在 SQLDA 中的标识长,那么将截断该标识并返回警告 (SQLSTATE 01665); 但是,当截断结构化类型的名称时,将返回错误 (SQLSTATE 42622)。 有关标识长度限制的详细信息,请参阅 SQL 和 XQuery 限制

SQLTYPE 和 SQLLEN

表 4 显示了 SQLDA 的 SQLTYPE 和 SQLLEN 字段中可能出现的值。 在 DESCRIBE 和 PREPARE INTO 中, SQLTYPE 的偶数值表示该列不允许空值,而奇数值表示该列不允许空值。 在 FETCH , OPEN 和 EXECUTE 中, SQLTYPE 的偶数值表示不提供指示符变量,而奇数值表示 SQLIND 包含指示符变量的地址。
表 4. DESCRIBE , FETCH , OPEN 和 EXECUTE 的 SQLTYPE 和 SQLLEN 值
SQLTYPE DESCRIBE 和 PREPARE INTO 的列数据类型 DESCRIBE 和 PREPARE INTO 的 SQLLEN FETCH , OPEN 和 EXECUTE 的主变量数据类型 FETCH , OPEN 和 EXECUTE 的 SQLLEN
384/385 日期 10 日期的固定长度字符串表示 主变量的 length 属性
388/389 时间 8 时间的固定长度字符串表示 主变量的 length 属性
392/393 时间戳记 19 表示 TIMESTAMP (0) ,否则 20 +p 表示 TIMESTAMP (p) 时间戳记的固定长度字符串表示 主变量的 length 属性
400/401 不适用 不适用 以 NULL 结束的图形字符串 主变量的 length 属性
404/405 BLOB 0 * BLOB 未使用。 *
408/409 CLOB 0 * CLOB 未使用。 *
412/413 DBCLOB 0 * DBCLOB 未使用。 *
448/449 可变长度字符串 列的 length 属性 可变长度字符串 主变量的 length 属性
452/453 定长字符串 列的 length 属性 定长字符串 主变量的 length 属性
456/457 长变长字符串 列的 length 属性 长变长字符串 主变量的 length 属性
460/461 不适用 不适用 以 NULL 结束的字符串 主变量的 length 属性
464/465 可变长度图形字符串 列的 length 属性 可变长度图形字符串 主变量的 length 属性
468/469 固定长度图形字符串 列的 length 属性 固定长度图形字符串 主变量的 length 属性
472/473 长变长图形字符串 列的 length 属性 长图形字符串 主变量的 length 属性
480/481 浮点 8 表示双精度, 4 表示单精度 浮点 8 表示双精度, 4 表示单精度
484/485 压缩十进制 字节 1 中的精度; 字节 2 中的小数位 压缩十进制 字节 1 中的精度; 字节 2 中的小数位
492/493 大整数 8 大整数 8
496/497 大整数 4 大整数 4
500/501 小整数 2 小整数 2
908/909 可变长度二进制字符串 列的 length 属性 可变长度二进制字符串 主变量的 length 属性
912/913 固定长度二进制字符串 列的 length 属性 固定长度二进制字符串 主变量的 length 属性
916/917 不适用 不适用 BLOB 文件引用变量 267
920/921 不适用 不适用 CLOB 文件引用变量 267
924/925 不适用 不适用 DBCLOB 文件引用变量。 267
960/961 不适用 不适用 BLOB 定位器 4
964/965 不适用 不适用 CLOB 定位器 4
968/969 不适用 不适用 DBCLOB 定位器 4
988/989 XML 0 not applicable; use an XML AS <string or binary 业务线 type> host variable instead 未使用
996 十进制浮点数 8 表示 DECFLOAT (16) , 16 表示 DECFLOAT (34) 十进制浮点数 8 表示 DECFLOAT (16) , 16 表示 DECFLOAT (34)
2440/2441 不适用 未使用
2440/2441 CURSOR 不适用 未使用
注:
  • 辅助 SQLVAR 中的 len.sqllonglen 字段包含列的长度属性。
  • 由于可移植性原因, SQLTYPE 已从先前版本更改。 继续支持先前版本中的值 (请参阅先前版本的 SQL 参考)。

无法识别且不受支持的 SQLTYPEs

SQLDA 的 SQLTYPE 字段中显示的值取决于在发送方和数据接收方上可用的数据类型支持级别。 随着新数据类型添加到产品中,这一点尤为重要。

新的数据类型可能由数据的发送方或接收方支持,也可能由数据的发送方或接收方识别,甚至可能由数据的发送方或接收方识别。 根据情况,可能返回新的数据类型,或者可能返回数据的发送方和接收方都同意的兼容数据类型,或者可能导致错误。

当发送方和接收方同意使用兼容数据类型时,下表指示将执行的映射。 当至少一个发送方或接收方不支持所提供的数据类型时,将执行此映射。 应用程序或数据库管理器可以提供不受支持的数据类型。

数据类型 兼容数据类型
BIGINT DECIMAL (19 和 0)
ROWID VARCHAR (40) for BIT 数据

请注意, SQLDA 中没有指示数据类型被替换。

压缩十进制数

压缩十进制数以二进制编码十进制 (BCD) 表示法的变体存储。 在 BCD 中,每个字符 (4 位) 代表一个十进制数字。 例如, 0001 0111 1001 表示 179。 因此,请通过 nybble 读取压缩十进制值 nybble。 存储该值 (以字节为单位) ,然后以十六进制表示法读取这些字节以返回到十进制。 例如, 0001 0111 1001 在二进制表示中变为 00000001 01111001。 通过将此数字读为十六进制,它将变为 0179。

小数点由小数位决定。 例如,对于 DEC (12, 5) 列,最右边的 5 数字位于小数点的右边。

符号由代表数字的尼伯勒右边的一个尼伯勒指示。 正号或负号如下所示:

表 5。 压缩十进制数的符号指示符的值
签署 二进制表示 十进制表示法 用十六进制表示
正数 (+) 1100 12 C
负数 (-) 1101 13 D
总而言之:
  • 要存储任何值,请分配 p/2 + 1 字节,其中 p 是精度。
  • 从左到右分配 nybbles 以表示值。 如果某个数字具有偶数精度,那么将添加前导零 nybble。 此分配包括前导 (微不足道) 和尾部 (显着) 零位数。
  • 标志 nybble 将是最后一个字节的第二个 nybble。

例如:

按字节分组的十六进制 Nybbles
DEC (8 3) 6574.23 00 65 74 23 0C
DEC (6, 2) -334.02 00 33 40 2D
DEC (7 5) 5.2323 05 23 23 0C
DEC(5,2) -23.5 02 35 0D

用于十进制的 SQLLEN 字段

SQLLEN 字段包含十进制列的精度 (第一个字节) 和小数位 (第二个字节)。 如果编写可移植应用程序,那么应该单独设置精度和小数位字节,而不是将它们一起设置为短整数。 这将避免整数字节反转问题。

例如,在 C 中:
  ((char *)&(sqlda->sqlvar[i].sqllen))[0] = precision;
  ((char *)&(sqlda->sqlvar[i].sqllen))[1] = scale;