返回首页

gbase数据、南大通用产品文档:GBase8s处理未知的列列表

更新日期:2024年09月11日


本部分描述如何使用系统描述符区域来处理 INSERT...VALUES 语句。

要使用系统描述符区域来处理 INSERT 中的输入参数:

1. (以 PREPARE 语句)准备 INSERT 语句来给它一个语句标识符。
2. 以 ALLOCATE DESCRIPTOR 语句分配系统描述符区域。
3. 以 DESCRIBE...USING
SQL
DESCRIPTOR 语句来确定列的数目和数据
类型。
对于选择列表中的每一列,
DESCRIBE 语句填充一个项描述符。

以 GET DESCRIPTOR 语句来在主变量中保存未知的列的数目,其包含 COUNT 字
段的值。

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 532 -

4. 以 SET
DESCRIPTOR 语句将列设置为它们的值,其设置恰当的 DATA
和 VALUE 字段。该列值必须与它们相关联的列的数据类型相兼容。
如果您想要插入 NULL 值,则请将 INDICATOR 字段设置为 -1,并
不在 SET DESCRIPTOR 语句中指定任何 DATA 字段。
执行 INSERT 语句来将值插入至数据库内。
后面的部分演示如何执行简单的 INSERT 语句,其仅插入一行,以及使用插入游标
来从插入缓冲区插入几行的演示。

以 DEALLOCATE DESCRIPTOR 语句释放系统描述符区域。
执行简单的插入
下列步骤概括如何以系统描述符区域执行简单的 INSERT 语句:
(以 PREPARE 语句)准备 INSERT 语句,并给它一个语句标识符。
以 SET DESCRIPTOR 语句将该列设置为它们的值。
以 EXECUTE...USING SQL DESCRIPTOR 语句执行 INSERT 语句。
执行动态 INSERT 语句的样例程序
此样例程序展示如何执行动态 INSERT 语句。此 INSERT 语句不与插入游标相关联。


该程序将两个 TEXT 值插入至 txt_a 表内。
它从名为 desc_ins.txt 的命名的文件读取
该文本值。
然后,
该程序从此表选择列,
并将 TEXT 值存储在两个命名的文件 txt_out1 和
txt_out2 中。该程序说明使用系统描述符区域来处理列列表中的列。

=================================================================
======
1. EXEC SQL include locator;
2. EXEC SQL include sqltypes;
3. main()
4. {
5. EXEC SQL BEGIN DECLARE SECTION;
6. int ;
7. int cnt;
8. ifx_loc_t loc1;
9. ifx_loc_t loc2;
10. EXEC SQL END DECLARE SECTION;
11. EXEC SQL create database txt_test;

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 533 -

12. chkerr("CREATE DATABASE txt_test");
13. EXEC SQL create table txt_a (t1 text not null, t2 text);
14. chkerr("CREATE TABLE t1");
15. /* The INSERT statement could have been created at runtime. */
16. EXEC SQL prepare sid from 'insert into txt_a values (?, ?)';
17. chkerr("PREPARE sid");

=====================================================================
==

5 - 10 行

这些行声明主变量来保存要插入的列值(从用户获得)。


15 - 17 行

这些行为该语句组装字符串,并准备它作为 sid 语句标识符。该输入参数指定
INSERT 语句的找不到的行。INSERT 语句在此为硬编码,但可在运行时刻创建它。
=================================================================
======
18. EXEC SQL allocate descriptor 'desc';
19. chkerr("ALLOCATE DESCRIPTOR desc");
20. EXEC SQL describe sid using sql descriptor 'desc';
21. chkerr("DESCRIBE sid");
22. EXEC SQL get descriptor 'desc' :cnt = COUNT;
23. chkerr("GET DESCRIPTOR desc");
24. for (i = 1; i <= cnt; i++)
25. prsysdesc(i);

=====================================================================
==

18 和 19 行

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 534 -


要能够使用列的系统描述符区域,
您必须首先分配该系统描述符区域。
此 ALLOCATE
DESCRIPTOR 语句分配名为 desc 的系统描述符区域。


20 和 21 行

DESCRIBE 语句为 sid 标识的准备好的 INSERT 描述列。此 DESCRIBE 语句包括
USING SQL DESCRIPTOR 子句来指定 desc 系统描述符区域作为这些列描述的位置。


22 和 23 行

GET DESCRIPTOR 语句获得由 DESCRIBE 发现的列的数目(COUNT 字段)。在
cnt 主变量中存储此数目。


24 和 25 行

对于 INSERT 语句的列,此 for 循环详细检查项描述符。它使用 cnt 变
量来确定由 DESCRIBE 初始化的项描述符的数目。对于每一项描述符,
prsysdesc() 函数在主变量中保存诸如数据类型、长度和名称这样的信息。

=================================================================
======
26. loc1.loc_loctype = loc2.loc_loctype = LOCFNAME;
27. loc1.loc_fname = loc2.loc_fname = "desc_ins.txt";
28. loc1.loc_size = loc2.loc_size = -1;
29. loc1.loc_oflags = LOC_RONLY;
30. i = CLOCATORTYPE;
31. EXEC SQL set descriptor 'desc' VALUE 1
32. TYPE = :i, DATA = :loc1;
33. chkerr("SET DESCRIPTOR 1");
34. EXEC SQL set descriptor 'desc' VALUE 2

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 535 -

35. TYPE = :i, DATA = :loc2;
36. chkerr("SET DESCRIPTOR 2");
37. EXEC SQL execute sid using sql descriptor 'desc';
38. chkerr("EXECUTE sid");

=====================================================================
==

26 - 29 行

要插入 TEXT 值,该程序必须首先以 GBase 8s ESQL/C 定位符结构分配该值。loc1
定位符结构为 txt_a 表的 t1 列存储 TEXT 值;
loc2 是 txt_a 的 t2 列的定位符结构。
(参
见 13 行)

该程序包括 GBase 8s ESQL/Clocator.h 头文件
(1 行)
来定义 ifx_loc_t 结构。

两个 TEXT 值都位于名为 desc_ins.txt 的命名的文件(loc_loctype =
LOCFNAME)
中。
当您将 loc_size 字段设置为 -1 时,
该定位符结构告诉 GBase
8s ESQL/C 将 TEXT 值在单个操作中发送给数据库服务器。


30 - 36 行

第一个 SET DESCRIPTOR 语句设置 t1 列的项描述符中的 TYPE 和 DATA 字段
(VALUE 1)。该数据类型为 CLOCATORTYPE(在 GBase 8s ESQL/Csqltypes.h 头文件
中定义)来指示将列值存储在 GBase 8s ESQL/C 定位符结构中;将该数据设置为 loc1 定
位符结构。第二个 SET DESCRIPTOR 语句对 t2 列值执行相同的任务;它将它的 DATA
字段设置为 loc2 定位符结构。


37 和 38 行

数据库服务器以 EXECUTE...USING SQL DESCRIPTOR 语句执行 INSERT 语句,

从 desc 系统描述符区域获得新的列值。

=================================================================
======
39. loc1.loc_loctype = loc2.loc_loctype = LOCFNAME;

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 536 -

40. loc1.loc_fname = "txt_out1";
41. loc2.loc_fname = "txt_out2";
42. loc1.loc_oflags = loc2.loc_oflags = LOC_WONLY;
43. EXEC SQL select * into :loc1, :loc2 from a;
44. chkerr("SELECT");
45. EXEC SQL free sid;
46. chkerr("FREE sid");
47. EXEC SQL deallocate descriptor 'desc';
48. chkerr("DEALLOCATE DESCRIPTOR desc");
49. EXEC SQL close database;
50. chkerr("CLOSE DATABASE txt_test");
51. EXEC SQL drop database txt_test;
52. chkerr("DROP DATABASE txt_test");
53 EXEC SQL disconnect current;
54. }
55. chkerr(s)
56. char *s;
57. {
58. if (SQLCODE)
59. printf("%s error %d\n", s, SQLCODE);
60. }

=====================================================================
==

39 - 44 行

该程序使用 loc1 和 loc2 定位符结构来选择插入的值。将这些 TEXT 值读取至命名
的文件:t1 列(在 loc1 中)读取至 txt_out1,t2 列(在 loc2 中)读取至 txt_out2。
LOC_WONLY 的 loc_oflags 值意味着此 TEXT 数据重写这些输出文件中任何现有的数
据。


45 - 48 行

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 537 -


FREE 语句(45 行)释放为 sid 准备好的语句分配的资源。一旦释放了准备好的语
句,在该程序中就不可再次使用它。DEALLOCATE DESCRIPTOR 语句(46 行)释放分
配给 desc 系统描述符区域的内存。

55 - 60 行

chkerr() 函数是一个简单的异常处理例程。它为非零值检查全局的
SQLCODE 变量。由于零指示 SQL 语句的成功执行,因此,每当发生运行时刻错
误时,都执行 printf()(58 行)。
执行与游标相关联的 INSERT
对于从插入缓冲区插入行的 INSERT 语句的列列表值,您的 GBase 8s
ESQL/C 程序必须仍使用 DESCRIBE 和 SET DESCRIPTOR 语句来使用系统描述符
区域。它还必须随同插入游标使用 PUT...USING
SQL
DESCRIPTOR 语句,如下:
准备 INSERT 语句,并以 DECLARE 语句将它与插入游标相关联。所有多行
INSERT 语句都必须有一声明了的插入游标。
以 OPEN 语句为 INSERT 语句创建该游标。
以 PUT 语句及其 USING SQL DESCRIPTOR 子句来将第一组列插入至插入缓冲区
内。
在此 PUT 语句之后,
将存储在指定的系统描述符区域中的列值存储在插入缓冲区中。
在循环内重复该 PUT 语句,直到没有更多的行要插入为止。
在插入所有行之后,退出该循环,并以 FLUSH 语句刷新该插入缓冲区。
以 CLOSE 语句关闭该插入游标。

您处理该插入游标的方式,与您处理与 SELECT 语句相关联的游标的方式
相同。

参数说明:设置执行作业所使用的内存。
该参数属于USERSET 类型参数,请参考表15-1 中对应设置方法进行设置。
取值范围:0,或大于32M 的整型,默认单位为KB。
默认值:0
须知:

如果设置的query_mem 值大于0,
在生成执行计划时,
优化器会将作业的估算内存
调整为该值。

如果设置值为负数或小于32MB,将设置为默认值0,此时优化器不会根据该值调
整作业的估算内存。

使用 LOGSIZE 配置参数可设置逻辑日志文件的大小。
对于您的数据库服务器系统最优的日志空间量取决于以下因素:

您的应用程序需求和应用程序经历的更新活动量。
更高的更新活动需要更大的日志
空间。

恢复时间目标 (RTO) 标准,用于在重新启动服务器并使服务器进入联机或静默方
式后,服务器从问题恢复所用时间量(以秒计)。
在灾难性事件的情况中,
要考虑您可以容许多少数据丢失。
更多频繁的日志备份
(该
备份可以减少数据和事务丢失所带来的风险),需要更大的日志空间。

是使用 Enterprise Replication 还是使用数据复制配置(例如,HDR 辅助服务器、
SD 辅助服务器或 RS 辅助服务器)。

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 298 -
这些复制服务都可以影响日志文件的数量和大小。如果您的系统使用其中任何一个
复制服务,请参阅高可用性集群配置或《GBase
8s
Enterprise
Replication 指南》
中的指南。
确定日志大小的指南:

通常,管理较少的大日志文件比管理大量的小日志文件要容易得多。

日志空间过多不会影响性能。但是,日志文件和日志空间不足却会影响性能,因为
数据库服务器将触发频繁的检查点。

BLOB 空间中没有登录的智能大对象,但是这些对象包含在创建对象的日志备份
中。这意味着对象将不会释放直到服务器备份创建了对象的日志。 因此,如果
BLOB 空间中的智能大对象频繁更新,您可能需要更加频繁的日志备份以获得
BLOB 空间中的更多可用空间。

对于生成少量日志数据的应用程序,请一开始使用 10 个日志文件,每个文件 10
MB。

对于生成大量日志数据的应用程序,请一开始使用 10 个日志文件,每个文件 100
MB。
有以下两种维护 RPO 策略的方式,这决定了在灾难性事件中所容许的数据丢失,例如,
数据服务器的丢失:

一种维护 RPO 策略的方式是使用自动日志备份,即一旦日志文件填满就触发日志
备份。这样就将数据丢失限制到在备份期间包含在日志文件中的事务以及在日志备
份期间发生的任何其他事务。

另一种维护 RPO 策略的方式是使用调度程序。您可以创建一个任务,该任务自上
次日志备份以来在设定的时间间隔内自动备份任何新的日志数据。这样就将数据丢
失限制到在设定时间间隔内没有进行备份的事务。有关使用调度程序的信息,请参
阅调度程序。
如果 RPO 策略是必需的,那么可以使用调度程序插入一个按适当频率执行的任务来维护
该策略。这样就在日常周期内的特定时间自动备份日志文件。如果日志空间在日志备份或
回收之前就已填满,
那么可以备份这些日志并添加新的日志文件以允许事务处理继续进行,
或者可以使用调度程序添加新的任务来检测此情况,并自动执行其中任一操作。
您可以随时添加日志文件,
并且当事务一致性需要时数据库服务器会自动添加日志文件
(例
如,可能占用大量日志空间的长事务)。
增加逻辑日志空间量的最简单的方法是添加另一逻辑日志文件。请参阅手动添加逻辑日志
文件。
以下表达式提供了示例总日志空间配置(以 KB 计):
LOGSIZE = (((connections * maxrows) * rowsize) / 1024) / LOGFILES
表达式元素
解释
LOGSIZE
指定每个逻辑日志文件的大小(以 KB 计)。

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 299 -
表达式元素
解释
connections
为您在 sqlhosts 文件或注册表以及在 NETTYPE 参数中指定的所有
网络类型指定最大连接数。如果您通过在您的配置文件中设置多个
NETTYPE 配置参数来配置多个连接,
请为每个 NETTYPE 添加用户
字段,并替换前公式中 connections 的总数。
maxrows
指定在单个事务中要更新的最大行数。
rowsize
指定表行的平均大小(以字节计)。要计算 rowsize,请添加行中各列
的长度(来自 syscolumns 系统目录表)。
1024
将 LOGSIZE 转换为指定的单位 (KB)。
LOGFILES
指定逻辑日志文件的数量。

估计记录智能大对象时的日志大小
如果计划记录智能大对象用户数据,那么必须确保日志大小比正写入的数据量大得多。 如
果您将智能大对象存储在标准智能大对象空间中,那么始终记录元数据(即使不记录智能
大对象)。如果您将智能大对象存储在临时智能大对象空间中,那么根本不存在日志记录。


估计逻辑日志文件的数量
LOGFILES 参数提供系统初始化或重新启动时逻辑日志文件的数量。如果所有逻辑日志文
件的大小相同,您可以如下所示计算分配给逻辑日志文件的总空间:
逻辑日志空间总数 = LOGFILES * LOGSIZE
如果数据库服务器包含不同大小的日志文件,
那么不能使用 (LOGFILES * LOGSIZE) 表达
式来来计算逻辑日志的大小。
必须改为将磁盘上的每个日志文件的大小相加。
检查 onstat -l
输出中的 size 字段。 有关更多信息,请参阅 onstat -l 命令。
有关 LOGSIZE、LOGFILES 和 NETTYPE 的信息,请参阅《GBase 8s 管理员参考》 中
有关配置参数的主题。