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 描述主变量。
- 使用 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 字段描述
- 基本 SQLVARs: 这些条目始终存在。 它们包含有关列,参数标记或主变量的基本信息,例如数据类型代码,长度属性,列名,主变量地址和指示符变量地址。
- 辅助 SQLVARs: 仅当根据先前概述的规则将 SQLVAR 条目数加倍时,才存在这些条目。 对于用户定义的类型 (不包括引用类型) ,它们包含用户定义的类型名称。 对于引用类型,它们包含引用的目标类型。 对于 LOB ,它们包含主变量的 length 属性以及指向包含实际长度的缓冲区的指针。 (单值类型和 LOB 信息不重叠,因此单值类型可以基于 LOB ,而不必强制将 DESCRIBE 上的 SQLVAR 条目数增加两倍。) 如果使用定位器或文件引用变量来表示 LOB ,那么不需要这些条目。
DESCRIBE 对 SQLDA 的影响中详细描述了由 DESCRIBE 设置 SQLVAR 条目的情况。
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 实例中的字段
| 姓名 | 数据类型 | 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 字符串,如下所示:
使用 XML 数据时,可以设置 sqlname 以指示 XML 子类型,如下所示:
|
出现辅助 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 列中的名称。 例如:
|
|||
DESCRIBE 对 SQLDA 的影响
对于 DESCRIBE OUTPUT 或 PREPARE OUTPUT INTO 语句,数据库管理器始终将 SQLD 设置为结果集中的列数或输出参数标记数。 对于 DESCRIBE INPUT 或 PREPARE INPUT INTO 语句,数据库管理器始终将 SQLD 设置为语句中的输入参数标记数。 请注意,在输入描述符和输出描述符中都描述了与 CALL 语句中的 INOUT 参数对应的参数标记。
- 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)。
- 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
| 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 | 不适用 | 行 | 未使用 |
注:
|
||||
无法识别且不受支持的 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 数字位于小数点的右边。
符号由代表数字的尼伯勒右边的一个尼伯勒指示。 正号或负号如下所示:
| 签署 | 二进制表示 | 十进制表示法 | 用十六进制表示 |
|---|---|---|---|
| 正数 (+) | 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 字段包含十进制列的精度 (第一个字节) 和小数位 (第二个字节)。 如果编写可移植应用程序,那么应该单独设置精度和小数位字节,而不是将它们一起设置为短整数。 这将避免整数字节反转问题。
((char *)&(sqlda->sqlvar[i].sqllen))[0] = precision;
((char *)&(sqlda->sqlvar[i].sqllen))[1] = scale;