使用WHERE CURRENT OF 子句(ESQL/C、SPL)
使用 WHERE CURRENT OF 子句来更新 FOR UPDATE 声明了的游标的当前行,或更新 Collection 游标的当前元素。
在此,不可指定游标名称做为主变量。
当前行是最近获取的行。由于 UPDATE 语句不会将游标前进到下一行,因此通过此操作不更改在游标的活动集合内当前行的位置。
对于 GBase 8s 的表层级,您不可使用此子句,如果您正在仅从表层级中一个表选择的话。也就是说,如果您使用 ONLY 关键字,则您不可使用此选项。
在 ESQL/C 例程中,要包括 WHERE CURRENT OF 关键字,您必须提前已经使用了 DECLARE 语句来定义带有 FOR UPDATE 选项的游标。如果创建了该游标的 DECLARE 语句指定了 FOR UPDATE 中的一个或多个列,则限制您仅可更新随后的 UPDATE ... WHERE CURRENT OF 语句中的那些行。在 DECLARE 语句的 FOR UPDATE 子句中指定列的优势在于速度。如果在 DECLARE 语句中指定列,数据库服务器通常可更快地执行更新。
在 SPL 例程中,您可在 UPDATE 语句中的 WHERE CURRENT OF 关键字之后指定游标,仅当您在 SPL 的 FOREACH 语句中声明了 cursor_id。您不可在 SPL 例程中使用 DECLARE 语句来声明动态游标的名称,以及将那个游标与 PREPARE 语句已在同一 SPL 例程中声明了的准备好的对象的语句标识符相关联。
说明: Update 游标可执行以 UPDATE 语句不可能执行的更新。
下列 GBase 8s ESQL/C 示例说明 WHERE 子句的 CURRENT OF 形式。在此示例中,在收到 10% 折扣的客户的范围内(假设将新列 discount 添加到 customer 表)执行更新。在 WHILE 循环的外部准备 UPDATE 语句来确保仅执行一次解析。
char answer [1] = 'y';
EXEC SQL BEGIN DECLARE SECTION;
char fname[32],lname[32];
int low,high;
EXEC SQL END DECLARE SECTION;
main()
{
EXEC SQL connect to 'stores_demo';
EXEC SQL prepare sel_stmt from
'select fname, lname from customer
where cust_num between ? and ? for update';
EXEC SQL declare x cursor for sel_stmt;
printf("\nEnter lower limit customer number: ");
scanf("%d", &low);
printf("\nEnter upper limit customer number: ");
scanf("%d", &high);
EXEC SQL open x using :low, :high;
EXEC SQL prepare u from
'update customer set discount = 0.1 where current of x';
while (1)
{
EXEC SQL fetch x into :fname, :lname;
if ( SQLCODE == SQLNOTFOUND) break;
}
printf("\nUpdate %.10s %.10s (y/n)?", fname, lname);
if (answer = getch() == 'y')
EXEC SQL execute u;
EXEC SQL close x;
}
更新 Row 变量(ESQL/C)
带有“集合派生的表”段的 UPDATE 语句允许您在 row 变量中更新字段。“集合派生的表”段标识要在其中更新字段的 row 变量。要获取更多信息,请参阅 集合派生表。
要更新字段
- 在您的 GBase 8s ESQL/C 程序中创建 row 变量。
- 可选地,以 SELECT 语句(不带有“集合派生的表”段)将 ROW 类型列选择到 row 变量内。
- 以 UPDATE 语句和“集合派生的表”段更新 row 变量的字段。
- 在 row 变量包含正确的字段之后,您使用表或视图名称上的 UPDATE 或 INSERT 语句来将 row 变量保存在 ROW 列(命名的或未命名的)之中。
UPDATE 语句和“集合派生的表”段允许您在 row 变量中更新字段或字段的组。 请在 SET 子句中指定新的字段值。例如,下列 UPDATE 更改 myrect GBase 8s ESQL/C row 变量中的 x 和 y 字段:
EXEC SQL BEGIN DECLARE SECTION;
row (x int, y int, length float, width float) myrect;
EXEC SQL END DECLARE SECTION;
. . .
EXEC SQL select into :myrect from rectangles where area = 64;
EXEC SQL update table(:myrect) set x=3, y=4;
假设在 SELECT 语句之后,myrect2 变量有值 x=0、y=0、length=8 以及 width=8。 在 UPDATE 语句之后,myrect2 变量有字段值 x=3、y=4、length=8,以及 width=8。 您不可使用 INSERT 语句的“集合派生的表”段中的 row 变量。
然而,您可使用 UPDATE 语句和“集合派生的表”段来将新字段插入到 row 主变量之内,如果您为该行中的每个字段都指定值的话。
例如,下列代码片段将新的字段值插入到 row 变量 myrect 内,然后将此 row 变量插入到数据库之内:
EXEC SQL update table(:myrect)
set x=3, y=4, length=12, width=6;
EXEC SQL insert into rectangles
values (72, :myrect);
如果该 row 变量是非类型的变量,则您必须在 UPDATE 之前使用 SELECT,以便 GBase 8s ESQL/C 可确定这些字段的数据类型。row 变量中字段的 UPDATE 不可包括 WHERE 子句。
row 变量可存储该行的字段值,但它没有与数据库列内在的连接。一旦 row 变量包含正确的字段值,您必须以下列 SQL 语句之一将该变量保存到 ROW 列内:
- 要以 row 变量的内容更新表中的 ROW 列,请在表或视图名称上使用 UPDATE 语句并在 SET 子句中指定该 row 变量。(要获取更多信息,请参阅 更新 ROW 类型列。)
- 要将 row 插入到列内,请在表或视图名称上使用 INSERT 语句并在 VALUES 子句中指定 row 变量。(要获取更多信息,请参阅 将值插入到 ROW 类型列内。)
要获取 SPL ROW 变量的示例,请参阅 GBase 8s SQL 教程指南。要获取关于使用 GBase 8s ESQL/C row 变量的更多信息,请参阅 GBase 8s ESQL/C 程序员手册 中对复杂数据类型的讨论。