用SQLJ开发数据库(6)

发表于:2007-07-14来源:作者:点击数: 标签:
用SQLJ 开发 数据库 (6) 迭代程序 在SQLJ程序中,SQL查询返回的结果集可以作为一个迭代程序对象,用来保存数据。迭代程序对象是迭代程序类的一个实例,并且在概念上类似于PL/SQL游标。我们必须执行下面的五个步骤来使用迭代程序处理SQL查询返回的数据。 声
用SQLJ开发数据库(6)

   迭代程序

   在SQLJ程序中,SQL查询返回的结果集可以作为一个迭代程序对象,用来保存数据。迭代程序对象是迭代程序类的一个实例,并且在概念上类似于PL/SQL游标。我们必须执行下面的五个步骤来使用迭代程序处理SQL查询返回的数据。

    声明迭代程序类。

    从迭代程序类声明一个迭代程序对象。

    使用SELECT语句添加迭代程序对象。

    从迭代程序对象中读取数据。

    关闭迭代程序对象。

   有二种类型的迭代程序类∶

    命名的迭代程序,在这种类型中,Java变量类型和迭代程序列名都必须被指定。

    位置迭代程序,在这个类型中,只有用于从数据库中检索得到的列的Java变量类型需要指定。

   命名迭代程序∶一个命名迭代程序声明指定了列存取器名和它们的Java类型。

   让我们来演示一下使用这个例程的五个步骤,在本例中我们想检索雇员表Emp中的Ename,Job和HireDate列,查找工资大于1500的雇员。

   声明迭代程序类∶


#sql iterator EmpIteratorClass(String Ename, String Job, Timestamp HireDate);

   我们使用Java String类来表示Ename和Job列,因为它兼容Oracle VARCHAR2数据库类型。

   java.sql.Timestamp类型用于HireDate列( Oracle的日期类型),因为java.sql.Date类型只能保存年份,日期和时间信息,而不能象java.sql.Timestamp一样保存小时,分钟和秒。

   从迭代程序类中声明迭代程序对象∶

    EmpIteratorClass empIterator;

   使用SQL SELECT语句添加迭代程序对象。

   下列SQLJ语句把Emp表的Ename,Job和HireDate列中的内容加入empIterator对象∶


int salary = 1500;
#sql empIterator = {
select Ename, Job, HireDate
from Emp
where Sal > :salary
};

   我们还要声明主变量salary,用于WHERE子句中来标识要从Emp表中返回什么数据。

   记住,通过SQL查询返回的数据库列的名称必须对应于第一步中定义迭代程序列名。从迭代程序对象中读取数据。因为迭代程序对象可能包含多个行,所以我们需要使用一个循环来访问每一行数据,就象我们从PL/SQL游标中读取数据一样。命名迭代程序实现一个next()方法,允许你在迭代程序对象的数据之间移动。此外,SQLJ还提供了检索迭代程序列的值得存取方法。下列代码在一个循环中打印出雇员姓名,职务和雇用日期。

while (empIterator.next()) {
System.out.println("Name: " + empIterator.Ename());
System.out.println("Job: " + empIterator.Job());
System.out.println("Hire Date:" +
empIterator.HireDate().toString());
}
empIterator.close();

关闭迭代程序对象∶<0}
empIterator.close();

   程序段一把从第2步到第5步联结起来演示了使用了命名迭代程序和empSalary参数的listEmployees ()方法。位置迭代程序∶与命名迭代程序相反,位置迭代程序只是指定了列的数目和种类,而不是它们的名称。列数据可以只通过位置访问,通过传统的FETCH... INTO语法。除了使用FETCH语句之外,还需要使用位置迭代程序方法endFetch ()来检测结束条件从而从循环中跳出。但是必须在访问所需要取得的数据之间检查条件。

   下面是相同的五个步骤,演示如何使用位置迭代程序:

   声明迭代程序类∶

    #sql iterator EmpIteratorClass(String, String, Timestamp);

   从迭代程序类中声明迭代程序对象。还必须声明从迭代程序对象中取得的数据所必需的主变量。


EmpIteratorClass empIterator;
String name = null;
String job = null;
Timestamp hireDate = null;

   使用SQL SELECT语句加入迭代程序对象∶


int salary = 1500;
#sql empIterator = {
select Ename, Job, HireDate
from Emp
where Sal > :salary
};

   把数据从迭代程序对象中读入主机变量∶


while (true) {
#sql { FETCH :empIterator INTO :name, :job, :hireDate };
if (empIterator.endFetch()) {
break;
}

System.out.println("Name: " + name);
System.out.println("Job: " + job);
System.out.println("Hire Date:" + hireDate().toString());
}


   关闭迭代程序对象

    empIterator.close();

   把从第2步到第5步联结起来演示了使用了位置迭代程序和empSalary参数的listEmployees ()方法。可见,位置迭代程序对象所使用的语法很像PL/SQL游标的语法。命名迭代程序和位置迭代程序两者都执行基本相同的功能∶它们都保存SQL查询的结果,有可能还是很多行数据至于到底使用哪一种迭代程序则要看情况或是根据自己的偏爱;从性能角度上来看呢,它们产生的结果都是一样的。

(未完待续)
   可执行语句

   可执行的SQLJ语句在一对大括号内包含了静态的SQL操作。有两种可能的可执行语句,由SQL是否回来一个值来决定。下面是一个不返回值的嵌入式SQL语句的例子;它在Emp表的Ename列和Sal列上创建一个复合索引∶


#sql { create index EMP_ENAME_SAL on Emp(Ename, Sal) };

   如果一个嵌入式SQL语句返回值的话,你需要使用一个主机变量来指定结果应该放在什么地方。在本例子中,调用PL/SQL函数getSalary返回雇员号Empno为7900的雇员的工资。你可以使用VALUES或者SET运算符来调用函数;也就是说,


int salary;
int empNo = 7900;
#sql salary = { VALUES getSalary(:empNo} };
or
#sql { SET :salary = getSalary(:empNo) };

   主机表达式

   在上面的例子中,我们可以看到,主机变量允许SQLJ程序在数据库和Java程序之间交换信息。它们是任何在Java程序中声明的变量。主机变量被嵌入到SQLJ语句里,称作主机表达式。主机表达式把主机变量绑定在SQLJ可执行语句上,它们也可能包括Java数组元素,对象属性或者Java函数。SQLJ负责在SQL和Java环境之间来回移动数据。所有的标准JDBC类型-象Boolean,byte,short,int,String,byte [],double,float,java.sql.Date等等。?都是SQLJ中有效的主机表达式。此外,Oracle的SQLJ翻译器支持使用Oracle数据库类型,例如ROWID,CLOB,BLOB和Object以及REF类型。在本文中,我讨论了编写实际的SQLJ代码所必需用到的SQLJ对象类型:连接上下文,命名和位置迭代程序,可执行语句和主机表达式。在以后的文章里,我想编写一个服务器端SQLJ程序,编译它,然后把它配置进Oracle JServer并把它PL/SQL对应的程序进行性能上的比较。

代码段1
public static void listEmployees(String empSalary)
throws SQLException {
EmpIteratorClass empIterator;
Integer salary = new Integer(empSalary);
try {
#sql empIterator = {
select Ename, Job, HireDate
from Emp
where Sal > :salary
};
while (empIterator.next()) {
System.out.println("Name: " + empIterator.Ename());
System.out.println("Job: " + empIterator.Job());
System.out.println("Hire Date:" +
empIterator.HireDate().toString());
}
empIterator.close();
} catch (SQLException e) {
System.err.println("SQLException" + e);
System.exit(1);
}
}
代码段2
public static void listEmployees(String empSalary)
throws SQLException {
EmpIteratorClass empIterator;
Integer salary = new Integer(empSalary);
/*主机变量 */
String name = null;
String job = null;
Timestamp hireDate = null;
try {
#sql empIterator = {
select Ename, Job, HireDate
from Emp
where Sal > :salary
};
while (true) {
#sql { FETCH :empIterator INTO :name, :job, :hireDate };
if (empIterator.endFetch()) {
break;
}

System.out.println("Name: " + name);
System.out.println("Job: " + job);
System.out.println("Hire Date:" + hireDate().toString());
}
empIterator.close();
} catch (SQLException e) {
System.err.println("SQLException" + e);
System.exit(1);
}
}

原文转自:http://www.ltesting.net