返回首页

gbase数据、南大通用产品文档:GBase8s列绑定

更新日期:2024年09月11日

GCI 接口对于按列式绑定的模式支持相对简单,即每列对应数组,包括空值指示和长度
指示。内存块申请策略如图:

上图中:
有三个字段(A/B/C)访问,分别各自申请长度为2 的数组。
与其对应的空值指示也为各自申请长度为2 的类型为sb2 的数组

长度指示为长度为2 的ub2 类型数组

列绑定方式时,应用程序不需要使用GCIBindArrayOfStruct 或GCIDefineArrayOfStruct 接
口指定偏移量(如调用各个偏移量参数可设定为0)

为了以后插入到数据库内,使用 PUT 语句来在插入缓冲区中存储一行。
语法


GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 782
元素
描述
限制
语法
cursor_id
游标的名称
必须是打开的
标识符
cursor_id_var
主变量 = cursor_id
必须为字符类
型;游标必须是
打开的
特定于语言
descriptor
系统描述符区域的名称 必须已分配
引用字符串
descriptor_var
包含 descriptor 的主
变量
必须已分配
引用字符串
indicator_var
如果相应的
output_var 收到 NULL
值,则为要收到返回代
码的主变量
不可为
DATETIME 或
INTERVAL 数据
类型
特定于语言
output_var
其内容代替准备好的
INSERT 语句中的问号
(?)占位符的主变量
必须为字符数据
类型
特定于语言
sqlda_pointer
指向 sqlda 结构的指针
第一个字符不可
为($)或(:)
符号
DESCRIBE 语

用法
此语句为对 SQL 的 ANSI/ISO 标准的扩展。您可随同 ESQL/C 使用此语句。
PUT 将行存储在打开游标时创建的插入缓冲区中。
如果当该语句执行时该缓冲区没有空间存储新行,则将被缓冲的行成块写到数据
库,并清空缓冲区。因此,一些 PUT 语句执行导致将行写到数据库,而一些不
写。您可使用 FLUSH 语句来将缓冲的行写到数据库,而不添加新行。在关闭
Insert 游标之前,CLOSE 语句写所有余下的行。
如果当前的数据库使用显式的事务,您必须在一事务之内执行 PUT 语句。
下列示例使用 GBase 8s ESQL/C 中的 PUT 语句:
EXEC SQL prepare ins_mcode from

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 783
'insert into manufact values(?,?)';
EXEC SQL declare mcode cursor for ins_mcode;
EXEC SQL open mcode;
EXEC SQL put mcode from :the_code, :the_name;
PUT 语句不是 X/Open SQL 语句。因此,如果您在 X/Open 模式下编译 PUT 语
句,则会得到警告信息。
提供插入的值
插入的行中的值可来自下列来源之一:

写到 INSERT 语句内的常量值

在 INSERT 语句中命名的程序变量

在 PUT 语句的 FROM 子句中的程序变量

在由 sqlda 结构寻址的内存中准备的值,或系统描述符区域,然后在
PUT 语句的 USING 子句中指定。
descriptor 或 sqlda_pointer 引用的系统描述符区域或 sqlda 结构必须定义每一值
的数据类型和内存位置,对应于准备好的 INSERT 语句中的问号(?)占位符。
在 INSERT 中使用常量值
VALUES 子句罗列插入的列的值。这些值中的一个或多个可为常量(即,数字或
字符串)。
当所有插入的值都是常量时,PUT 语句有一特殊的作用。PUT 语句仅增大计数
器,而不创建行并放入缓冲区中。当您使用 FLUSH 或 CLOSE 语句来清空缓冲区
时,将一行和重复计数发送到数据库服务器,插入那个编号的行。在下列 GBase
8s ESQL/C 示例中,将 99 个空客户记录插入到 customer 表内。因为所有值都
是常量,直到该游标关闭才会发生磁盘输出。(customer_num 的常量零导致生成
SERIAL 值。)下列示例将 99 个空客户记录插入到客户表内:
int count;
EXEC SQL declare fill_c cursor for
insert into customer(customer_num) values(0);
EXEC SQL open fill_c;
for (count = 1; count <= 99; ++count)
EXEC SQL put fill_c;
EXEC SQL close fill_c;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 784
在 INSERT 中命名程序变量
当您将 INSERT 语句与游标(在 DECLARE 语句中)相关联时,请创建 Insert
游标。在 INSERT 语句中,您可在 VALUES 子句中命名程序变量。当执行每一
PUT 语句时,使用那个时刻的程序变量的内容来填写插入到缓冲区内的行。
如果您正在(随同 INSERT 使用 DECLARE)创建 Insert 游标,则必须在该
VALUES 子句中仅使用程序变量。在准备好的语句的上下文中不识别变量名称;
您通过其语句标识符将准备好的语句与游标关联。
下列 GBase 8s ESQL/C 示例展示 Insert 游标的使用。代码包括下列语句:

DECLARE 语句将名为 ins_curs 的游标与 INSERT 语句相关联,该
INSERT 语句将数据插入到 customer 表内。

VALUES 子句指定名为 cust_rec 的数据结构;GBase 8s ESQL/C 预处理
器将 cust_rec 转化为值的列表,每一结构的组件一个。

OPEN 语句创建一缓冲区。

用户定义的函数(未在此示例内定义)从用户输入获取客户信息并将其保
存在 cust_rec 中。

PUT 语句从 cust_rec 结构的当前内容组成一行,并将其发送到行缓冲
区。

CLOSE 语句将留在行缓冲区中的任何行都插入到 customer 表内,并关闭
Insert 游标:
int keep_going = 1;
EXEC SQL BEGIN DECLARE SECTION
struct cust_row { /* fields of a row of customer table */ } cust_rec;
EXEC SQL END DECLARE SECTION
EXEC SQL declare ins_curs cursor for
insert into customer values (:cust_row);
EXEC SQL open ins_curs;
while ( (sqlca.sqlcode == 0) && (keep_going) )


{
keep_going = get_user_input(cust_rec); /* ask user for new customer */
if (keep_going ) /* user did supply customer info
*/

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 785
{
cust_rec.customer_num = 0; /* request new serial value */
EXEC SQL put ins_curs;
}
if (sqlca.sqlcode == 0) /* no error from PUT */
keep_going = (prompt_for_y_or_n("another new customer") =='Y')
}
EXEC SQL close ins_curs;
如果插入的数据可能为 NULL ,则请使用指示符变量。
当准备 INSERT 语句时(请参阅 PREPARE 语句),您不可在它的 VALUES
子句中使用程序变量,但可通过问号(?)占位符表示值。请在 PUT 语句的
FROM 子句中罗列程序变量来提供缺少的值。
下列 GBase 8s ESQL/C 示例罗列在 PUT 语句中的主变量:
char answer [1] = 'y';
EXEC SQL BEGIN DECLARE SECTION;
char ins_comp[80];
char u_company[20];
EXEC SQL END DECLARE SECTION;

main()
{
EXEC SQL connect to 'stores_demo';
EXEC SQL prepare ins_comp from
'insert into customer (customer_num, company) values (0, ?)';
EXEC SQL declare ins_curs cursor for ins_comp;
EXEC SQL open ins_curs;

while (1)
{
printf("\nEnter a customer: ");
gets(u_company);
EXEC SQL put ins_curs from :u_company;
printf("Enter another customer (y/n) ? ");
if (answer = getch() != 'y')
break;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 786
}
EXEC SQL close ins_curs;
EXEC SQL disconnect all;
}
指示符变量是可选的,但如果可能存在包含 NULL 值的 output_var ,则您应使
用指示符变量。如果您指定未带 INDICATOR 关键字的指示符变量,则不可在
output_var 与 indicator_var 之间放空格。
命名 PUT 中的程序变量
当准备 INSERT 语句时(请参阅 PREPARE 语句),您不可在它的 VALUES
子句中使用程序变量,但可通过问号(?)占位符表示值。请在 PUT 语句的
FROM 子句中罗列程序变量来提供缺少的值。
下列 GBase 8s ESQL/C 示例罗列在 PUT 语句中的主变量:
char answer [1] = 'y';
EXEC SQL BEGIN DECLARE SECTION;
char ins_comp[80];
char u_company[20];
EXEC SQL END DECLARE SECTION;

main()
{
EXEC SQL connect to 'stores_demo';
EXEC SQL prepare ins_comp from
'insert into customer (customer_num, company) values (0, ?)';
EXEC SQL declare ins_curs cursor for ins_comp;
EXEC SQL open ins_curs;

while (1)
{
printf("\nEnter a customer: ");
gets(u_company);
EXEC SQL put ins_curs from :u_company;
printf("Enter another customer (y/n) ? ");
if (answer = getch() != 'y')
break;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 787
}
EXEC SQL close ins_curs;
EXEC SQL disconnect all;
}
指示符变量是可选的,但如果可能存在包含 NULL 值的 output_var ,则您应使
用指示符变量。如果您指定未带 INDICATOR 关键字的指示符变量,则不可在
output_var 与 indicator_var 之间放空格。
使用 USING 子句
如果您不知道在运行时要提供的参数的数目或其数据类型,则可从系统描述符或
sqlda 结构关联输入值。这些描述符结构都描述一个或多个替代问号(?)占位符
的值的数据类型和内存位置。
每次执行 PUT 语句,都使用描述符结构描述的值替代 INSERT 语句中的问号
(?)占位符。此过程类似于随同变量列表使用 FROM 子句,除了您的程序可完
全控制数据值的内存位置之外。
指定系统描述符区域
SQL DESCRIPTOR 选项指定系统描述符区域的名称。
系统描述符区域中的 COUNT 域对应于准备好的语句中动态参数的数目。
COUNT 的值必须小于或等于当以 ALLOCATE DESCRIPTOR 分配系统描述符区
域时指定的项描述符的数量。您可以 GET DESCRIPTOR 语句取得域值,并以
SET DESCRIPTOR 语句设置该值。
系统描述符区域符合 X/Open 标准。
下列 GBase 8s ESQL/C 示例展示如何从系统描述符区域关联值:
EXEC SQL allocate descriptor 'desc1';
...
EXEC SQL put selcurs using sql descriptor 'desc1';
指定 sqlda 结构
使用 DESCRIPTOR 选项来引入指向 sqlda 结构的指针的名称。下列 GBase 8s
ESQL/C 示例展示如何从 sqlda 结构关联值:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 788
EXEC SQL put selcurs using descriptor pointer2;
插入到 Collection 游标内
Collection 游标允许您访问集合变量的单个元素。 要声明 Collection 游标,请使
用 DECLARE 语句并包括在您将其与游标关联的 INSERT 语句中的“集合派生的
表”段。一旦您以 OPEN 语句打开 Collection 游标,该游标可将元素放在集合变
量中。
要一次一个地将元素放到 Insert 游标内,请使用 PUT 语句和 FROM 子句。 PUT
语句指定与该集合变量相关联的 Collection 游标。 FROM 子句标识要被插入到
游标内的元素值。 在 FROM 子句中的任何主变量的数据类型必须与该集合的元素
类型相匹配。
Important: 集合变量存储集合的元素。然而,它与数据库列没有内在的联系。
一旦集合变量包含正确的元素,那么您必须以 INSERT 或 UPDATE 语句将该变量
保存到实际的集合列内。
假设您有一名为 children 的表,其模式如下:
CREATE TABLE children
(
age SMALLINT,
name VARCHAR(30),
fav_colors SET(VARCHAR(20) NOT NULL)
);
下列 GBase 8s ESQL/C 程序片断展示如何使用 Insert 游标将元素放入名为
child_colors 的集合变量内:
EXEC SQL BEGIN DECLARE SECTION;
client collection child_colors;
char *favorites[]
(
"blue",
"purple",
"green",
"white",
"gold",

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 789
0
);
int a = 0;
char child_name[21];
EXEC SQL END DECLARE SECTION;

EXEC SQL allocate collection :child_colors;

/* 获取 fav_colors 列的结构,对于 untyped
* child_colors 集合变量 */
EXEC SQL select fav_colors into :child_colors
from children where name = :child_name;
/* 为 child_colors 集合变量声明插入游标
* 并打开此游标 */
EXEC SQL declare colors_curs cursor for
insert into table(:child_colors)
values (?);
EXEC SQL open colors_curs;
/* 使用 PUT 来将 favorite-color 值收集
* 到游标内 */
while (fav_colors[a])
{
EXEC SQL put colors_curs from :favorites[:a];
a++
...
}
/* 刷新游标内容到集合变量 */
EXEC SQL flush colors_curs;
EXEC SQL update children set fav_colors = :child_colors;

EXEC SQL close colors_curs;
EXEC SQL deallocate collection :child_colors;
在 FLUSH 语句执行之后,集合变量 child_colors 包含元素 {"blue",
"purple", "green", "white", "gold"}。在此程序片断的末尾的
UPDATE 语句将新的集合保存到数据库的 fav_colors 列内。没有此 UPDATE
语句,就不会将新的集合插入到集合列。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 790
写缓冲了的行
要打开 Insert 游标,OPEN 语句创建插入缓冲区。PUT 语句将一行放到此插入
缓冲区内。仅当必要时,才将缓冲了的行成块插入到数据库表内;此过程称为刷
新缓冲区。在下列任何事件之后,都会刷新缓冲区:

缓冲区太满,以至于不能在 PUT 语句开始时保持新行。

FLUSH 语句执行。

CLOSE 语句关闭游标。

OPEN 语句指定已打开的游标,在重新打开它之前关闭它。(此隐式
CLOSE 语句刷新缓冲区。)

COMMIT WORK 语句执行。

缓冲区包含 BYTE 或 TEXT 语句(在单个 PUT 语句之后刷新)。
如果程序没有关闭 Insert 游标就终止,则缓冲区保持未刷新。自从上一次刷新以
来插入到该缓冲区内的行丢失。请不要依赖于程序的末尾来关闭游标并刷新缓冲
区。
错误检查
sqlca 结构包含每一 PUT 语句的成功信息,以及使您能对插入了的行进行计数的
信息。在 sqlca 的下列字段中包含每一 PUT 语句的结果:sqlca.sqlcode、
SQLCODE 和 sqlca.sqlerrd[2]。
带有 Insert 游标的数据缓冲区意味着直到刷新缓冲区时才发现错误。例如,仅当
刷新缓冲区时,才会发现输入值与所想要的列的数据类型不兼容。当发现错误
时,不插入那些在错误之前未被插入的那些缓冲了的行;它们会从内存丢失。
如果未发生错误,则 SQLCODE 域设置为 0;否则设置为错误代码。sqlerrd 数组
的第三个元素设置为成功地插入到了数据库内的行的数目:

如果将任何行放到插入缓冲区内,但未写到数据库,则SQLCODE 和
sqlerrd 设置为 0(SQLCODE 是因为未发生错误,sqlerrd 是因为未插
入行)。

如果在 PUT 语句执行期间,缓冲了的行块写到数据库,则 SQLCODE
设置为 0,且 sqlerrd 设置为成功地插入到数据库内的行的数目。

如果在将缓冲了的行写到数据库时发生错误,则 SQLCODE 指出错误,
且sqlerrd 包含成功地插入行的数目。(从缓冲区废弃未缓冲的行。)

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 791
提示: 当您遇到 SQLCODE 错误时,还存在 SQLSTATE 错误。请参阅 GET
DIAGNOSTICS 语句了解如何获取消息文本的细节。
要对在数据库中挂起和插入的行的数目计数
1. 准备两个整数变量(例如,total 和 pending)。
2. 当打开游标时,将两个变量设置为 0。
3. 每次执行 PUT 语句,增大 total 和 pending。
4. 无论何时执行 PUT 或 FLUSH 语句,或关闭游标,从 pending 减去
SQLERRD 数组的第三个字段。
在任何时候,(total - pending)都表示实际插入的行数。 如果没有语句失败,则
在关闭游标之后 pending 包含零。 如果在 PUT、FLUSH 或 CLOSE 期间发生
错误,则保留在 pending 中的值为未插入的(被废弃的)行的数目。
相关的语句
相关的语句:ALLOCATE DESCRIPTOR 语句、CLOSE 子句、DEALLOCATE
DESCRIPTOR 语句、FLUSH 语句、DECLARE 语句、GET DESCRIPTOR 语
句、OPEN 语句、PREPARE 语句 和 SET DESCRIPTOR 语句
要获得关于 PUT 语句的面向任务的讨论,请参阅 GBase 8s SQL 教程指南。
要获得更多关于错误检查、系统描述符区域和 sqlda 结构的信息,请参阅 GBase
8s ESQL/C 程序员手册。

ifx_dececvt() 和 ifx_decfcvt() 函数是 dececvt() 和 decfcvt()GBase 8s ESQL/C 库函数
的线程安全版本。
语法
mint ifx_dececvt(np, ndigit, decpt, sign, decstr, decstrlen)
register dec_t *np;
register mint ndigit;
mint *decpt;
mint *sign;
char *decstr;
mint decstrlen;

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

mint ifx_decfcvt(np, ndigit, decpt, sign, decstr, decstrlen)
register dec_t *np;
register mint ndigit;
mint *decpt;
mint *sign;
char *decstr;
mint decstrlen;
np
指向包含要被转换的 decimal 值的 decimal 结构的指针。
ndigit
ifx_dececvt() 的 ASCII 字符串的长度。它是 ifx_decfcvt() 的小数点的右边的位数。
decpt
指向整数的指针,该整数是小数点相对于该字符串的开头的位置。*decpt 的负值或零
值意味着该位置位于返回的数字的左边。
sign
指向结果的符号的指针。如果该结果的符号为负的,则 *sign 非零;否则,它为零。

decstr
函数将转换了的 decimal 值返回到其中的用户定义的缓冲区。
decstrlen
用户定义的 decstr 缓冲区的长度,以字节计。

用法
ifx_dececvt() 函数是 dececvt() 函数的线程安全版本。ifx_decfcvt() 函数是 decfcvt()
函数的线程安全版本。当两个线程同时调用该函数时,每一函数返回一个不可被重写的字
符串。

返回代码
0
转换成功。
<0
转换不成功。

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 702 -
-1273
输出缓冲区为空,或太小以至于不能保存结果。