如下表所示,EGL 生成的代码可以访问任何目标系统上的关系数据库。
目标系统 | 对访问关系数据库的支持 |
---|---|
AIX®、iSeries™、Linux™、Windows® 2000/NT/XP 和 UNIX® System Services | JDBC 提供了对 DB2® UDB、Oracle 或 Informix® 的访问 |
开发程序时,可以象使用大多数其它语言编写程序时那样编写 SQL 语句。为了方便您工作,EGL 提供了 SQL 语句模板来供您填写。
另一种方法是,在编写 EGL 语句时,可以将 SQL 记录用作 I/O 对象。以此方式使用记录意味着通过对提供给您的 SQL 语句进行定制或者通过依靠缺省 SQL 语句(从而不需要编写 SQL)来访问数据库。
select empnum, empname from employee where empnum >= :myRecord.empnum for update of empname
下表列示了可以用来访问关系数据库的 EGL 关键字。此表还显示了与每个关键字相对应的 SQL 语句的概述。例如,在编写 EGL add 语句时,将生成 SQL INSERT 语句。
可以使用 EGL open 语句来调用存储过程。 该存储过程由 EGL 外部编写的逻辑组成的并存储在数据库管理系统中,它也返回结果集。(另外,可以使用 EGL execute 语句来调用存储过程。)
下列各节提供有关处理结果集的详细信息。
如果您打算显式地编写 SQL 语句,则使用 EGL execute 语句,并有可能使用 EGL prepare 语句。
关键字/用途 | SQL 语句的概述 | 是否可以修改 SQL? |
---|---|---|
add 在数据库中添加一行;或者(如果使用 SQL 记录动态数组的话),根据连续数组元素的内容添加一组行。 |
INSERT row(如果指定动态数组,则重复地发生)。 | 是 |
close 释放未处理的行。 |
CLOSE cursor。 | 否 |
delete 从数据库中删除一行。 |
DELETE row。该行是通过下列两种方法的其中一种选择的:
|
否 |
forEach 标记在循环中运行的一组语句的开始。仅当指定的结果集可用时才会发生第一次迭代,并且该迭代会持续(在大多数情况下)至处理结果集的最后一行。 |
EGL 将 forEach 语句转换成在循环内部运行的 SQL FETCH 语句。 | 否 |
freeSQL 释放与动态预编译 SQL 语句相关联的所有资源,关闭与该 SQL 语句相关联的任何打开游标。 |
否 | |
get(也称为 get by key value)
从数据库中读取一行;或者(如果使用 SQL 记录动态数组的话),将连续的行读入数组的连续元素。 |
SELECT row,但仅当设置了 singleRow 选项时才如此。否则,下列规则适用:
|
是 |
get absolute 读取结果集中由 open 语句选择的用数字指定的行。 |
EGL 将 get absolute 语句转换为 SQL FETCH 语句。 | 否 |
get current 读取结果集中由 open 语句选择的游标已经定位的行。 |
EGL 将 get current 语句转换为 SQL FETCH 语句。 | 否 |
get first 读取结果集中由 open 语句选择的第一行。 |
EGL 将 get first 语句转换为 SQL FETCH 语句。 | 否 |
get last 读取结果集中由 open 语句选择的最后一行。 |
EGL 将 get last 语句转换为 SQL FETCH 语句。 | 否 |
get next 读取结果集中由 open 语句选择的下一行。 |
EGL 将 get next 语句转换为 SQL FETCH 语句。 | 否 |
get previous 读取结果集中由 open 语句选择的上一行。 |
EGL 将 get previous 语句转换为 SQL FETCH 语句。 | 否 |
get relative 读取结果集中由 open 语句选择的用数字指定的行。该行是根据结果集中的游标位置指定的。 |
EGL 将 get relative 语句转换为 SQL FETCH 语句。 | 否 |
execute 允许运行 SQL 数据定义语句(例如,CREATE TABLE 类型)或数据处理语句(例如,INSERT 或 UPDATE 类型);或者运行不以 SELECT 子句开头的预编译 SQL 语句。 |
您编写的 SQL 语句可用于数据库管理系统。
execute 的主要用途是编写单一 SQL 语句,该 SQL 语句在生成时要定义完整的格式,如以下示例所示:
try execute #sql{ // no space after "#sql" delete from EMPLOYEE where department = :myRecord.department }; onException myErrorHandler(10); end 定义了完整格式的 SQL 语句可以在 WHERE 子句中包含主变量。 |
是 |
open 从关系数据库中选择一组行,以供 get next 语句以后检索。 |
EGL 将 open 语句转换为 CALL 语句(用于访问存储过程),或转换为下列语句:
|
是 |
prepare 指定一个 SQL PREPARE 语句,该语句包含(可选)只有在运行时才知道的详细信息;通过运行 EGL execute 语句或者(如果 SQL 语句以 SELECT 开头的话)通过运行 EGL open 或 get 语句来运行预编译 SQL 语句。 |
EGL 将 prepare 语句转换为 SQL PREPARE 语句,后者始终是在运行时构造的。在 EGL prepare 语句的以下示例中,每个参数标记(?)都是由后续 execute 语句中的 USING 子句解析的:
myString = "insert into myTable " + "(empnum, empname) " + "value ?, ?"; try prepare myStatement from myString; onException // exit the program myErrorHandler(12); end try execute myStatement using :myRecord.empnum, :myRecord.empname; onException myErrorHandler(15); end |
是 |
replace 将更改了的行放回数据库中。 |
UPDATE row。该行是通过下列两种方法的其中一种选择的:
|
是 |
打开游标的语句和对该游标的行执行操作的语句是通过结果集标识一一相关的,该结果集标识在程序中的所有结果集标识、程序变量和程序参数中必须是唯一的。在打开游标的 open 语句中指定该标识,并在影响单个行的 get next、delete 和 replace 语句中以及在关闭游标的 close 语句中引用同一标识。有关其它详细信息,请参阅 resultSetID。
VGVar.handleHardIOErrors = 1; try open selectEmp forUpdate with #sql{ // no space after "#sql" select empname from EMPLOYEE where empnum >= :myRecord.empnum for update of empname }; onException myErrorHandler(8); // exits program end try get next from selectEmp into :myRecord.empname; onException if (sysVar.sqlcode != 100) myErrorHandler(8); // exit the program end end while (sysVar.sqlcode != 100) myRecord.empname = myRecord.empname + " " + "III"; try execute #sql{ update EMPLOYEE set empname = :empname where current of selectEmp }; onException myErrorHandler(10); // exits program end try get next from selectEmp into :myRecord.empname; onException if (sysVar.sqlcode != 100) myErrorHandler(8); // exits program end end end // end while; cursor is closed automatically // when the last row in the result set is read sysLib.commit;
如果您希望避免上一个示例中的一些复杂性,请考虑使用 SQL 记录。通过使用 SQL 记录,可以使代码简化以及使用不随数据库管理系统的改变而变化的 I/O 错误值。下一个示例等同于上一个示例,但使用名为 emp 的 SQL 记录:
VGVar.handleHardIOErrors = 1; try open selectEmp forUpdate for emp; onException myErrorHandler(8); // exits program end try get next emp; onException if (sysVar.sqlcode not noRecordFound) myErrorHandler(8); // exit the program end end while (sysVar.sqlcode not noRecordFound) myRecord.empname = myRecord.empname + " " + "III"; try replace emp; onException myErrorHandler(10); // exits program end try get next emp; on exception if (sysVar.sqlcode not noRecordFound) myErrorHandler(8); // exits program end end end // end while; cursor is closed automatically // when the last row in the result set is read sysLib.commit;
下列各节描述 SQL 记录。
add EMP;
VGVar.handleHardIOErrors = 1; try add EMP; onException if (EMP is unique) // if a table row // had the same key myErrorHandler(8); end end
您声明 SQL 记录部件并将每个记录项与关系表或视图中的一列相关联。可以通过 EGL 编辑器的检索功能让 EGL 自动执行此关联,如下面的声明时的数据库访问中所述。
只有基本类型的字段可以表示数据库列。
在声明 SQL 记录部件之后,声明基于该部件的 SQL 记录。
可以定义一组 EGL 语句,每个 EGL 语句都将 SQL 记录用作语句中的 I/O 对象。对于每个语句,EGL 提供了隐式 SQL 语句,该语句并未包含在源代码中,而是由 SQL 记录与 EGL 语句的组合所隐含的。例如,对于 EGL add 语句,隐式 SQL INSERT 语句将给定记录项的值放入相关联的表列。如果 SQL 记录包含未指定表列的记录项,则 EGL 根据一个假定来构造隐式 SQL 语句,即假定记录项名与列名完全相同。
Record Employee type sqlRecord { tableNames = [["EMPLOYEE"]], keyItems = ["empnum"] } empnum decimal(6,0); empname char(40); end
get EMP;
SELECT empnum, empname FROM EMPLOYEE WHERE empnum = :empnum
INTO :empnum, :empname
属性 defaultSelectCondition 中指定的任何主变量都必须位于作为动态数组基础的 SQL 记录之外。
有关隐式 SELECT 语句(这种语句随着关键字的变化而变化)的详细信息,请参阅 get 和 open。
如果从源代码中除去显式 SQL 语句,则隐式 SQL 语句(如果有的话)在生成时再次可用。
DataItem DeptNo { column = deptNo } end Record Dept type SQLRecord deptNo DeptNo; managerID CHAR(6); employees Employee[]; end Record Employee type SQLRecord employeeID CHAR(6); empDeptNo DeptNo; end Function getDeptEmployees(dept Dept) get dept.employees usingKeys dept.deptNo; end
不要象在某些语言中那样在 SQL 语句中对空指示符编写主变量。要测试可空主变量中的 NULL,请使用 EGL if 语句。也可以测试被截断值的检索,但仅当空指示符可用时才能这样做。
有关 NULL 处理的其它详细信息,请参阅 itemsNullable 和 SQL 项属性。
检索功能将创建一些记录项,每个这样的记录项都与相关表列同名(或几乎同名)。
不能检索使用 DB2 条件 WITH CHECK OPTIONS 定义的视图。
有关使用检索功能的更多详细信息,请参阅检索 SQL 表数据。有关命名的详细信息,请参阅设置 SQL 检索首选项。
要在声明时访问数据库,可在首选项页面中指定连接信息,如设置 SQL 数据库连接首选项中所述。
相关概念
动态 SQL
逻辑工作单元
resultSetID