通过 SQL 程序修改数据 / INSERT 语句 |
EXEC SQL BEGIN DECLARE SECTION; long last_ord = 1; struct { long int o_num; date o_date; long c_num; char o_shipinst[40]; char o_backlog; char o_po[10]; date o_shipdate; decimal o_shipwt; decimal o_shipchg; date o_paiddate; } ord_row; EXEC SQL END DECLARE SECTION; EXEC SQL BEGIN WORK; EXEC SQL INSERT INTO new_orders SELECT * FROM orders main WHERE 1 = (SELECT COUNT(*) FROM orders minor WHERE main.order_num = minor.order_num); EXEC SQL COMMIT WORK; EXEC SQL DECLARE dup_row CURSOR FOR SELECT * FROM orders main INTO :ord_row WHERE 1 < (SELECT COUNT(*) FROM orders minor WHERE main.order_num = minor.order_num) ORDER BY order_date; EXEC SQL DECLARE ins_row CURSOR FOR INSERT INTO new_orders VALUES (:ord_row); EXEC SQL BEGIN WORK; EXEC SQL OPEN ins_row; EXEC SQL OPEN dup_row; while(SQLCODE == 0) { EXEC SQL FETCH dup_row; if(SQLCODE == 0) { if(ord_row.o_num != last_ord) EXEC SQL PUT ins_row; last_ord = ord_row.o_num continue; } break; } if(SQLCODE != 0 && SQLCODE != 100) EXEC SQL ROLLBACK WORK; else EXEC SQL COMMIT WORK; EXEC SQL CLOSE ins_row; EXEC SQL CLOSE dup_row;
此示例以一个常规的 INSERT 语句开始,该语句查找该表的所有非重复的行,并将它们插入到另一表内,假定在程序启动之前已创建了该表。那个操作仅留下重复的行。(在演示数据库中,orders 表有唯一约束,不可有重复的行。假设此示例处理的是其他数据库。)
然后,前面示例中的代码声明两个游标。第一个称为 dup_row,返回表中的重复的行。由于 dup_row 仅用于输入,因此,它可使用 ORDER BY 子句来强制一些重复的顺序,而不是在 使用游标删除 页上的示例中使用的物理记录顺序。在此示例中,按重复的行的日期对它们排序,保留最早的日期,但您可基于该数据使用任何其他的顺序。
第二个游标 ins_row 是插入游标。此游标利用该能力来使用 C 结构 ord_row,以支持该行中所有列的值。
剩余的代码检查通过 dup_row 返回的行。它将来自每一组重复的行中的第一行插入到新表内,并忽略其余的。
为了简洁起见,前面的示例使用最简单的错误处理类型。如果在已处理了所有行之前发生错误,则该样例代码回滚活动的事务。