日期:2014-05-16  浏览次数:20489 次

【新闻翻译】Java JDBC 执行 DDL 和 SQLJ 存储过程
Java JDBC 执行 DDL 和 SQLJ 存储过程


序言
Java JDBC(Java Data Base Connectivity,Java 数据库连接)是一种用于执行 SQL 语句的 Java API,可以为多种关系数据库提供统一访问接口,它由一组用 Java 语言编写的类和接口组成。JDBC 为数据库应用开发人员、数据库前台工具开发人员提供了一个标准的 API,据此可以构建更高级的工具和接口,使数据库开发人员能够用纯 Java API 编写数据库应用程序。
DDL(Data Definition Language)是指数据定义语句用于定义和管理 SQL 模式、基本表、视图、索引和存储过程等数据库中的对象。
SQLJ 由一系列定义了 SQL 与 Java 之间相互作用的子句和程序扩充组成。SQLJ 是在 Java 编程语言中静态嵌入式 SQL。本文研究的 SQLJ 存储过程特指 DB2 数据库提供的内嵌 SQLJ 存储过程,例如 SQLJ.DB2_INSTALL_JAR 存储过程,它用于创建一个新定义的 JAR 文件到特定的数据库。
本文在系统分析利用数据库脚本文件执行 DDL 和 SQLJ 存储过程缺点的基础上,提出并详细介绍了利用 Java JDBC 执行 DDL 和 SQLJ 存储过程的方法。
回页首
方法提出的背景
在 Java 与数据库交互编程过程中,经常遇到这样的场景:需要执行大量的 DDL 语句和 SQLJ 存储过程,并且这些语句之间有着较强的依赖关系。下面是一个这样的例子,SQL 语句中既有多条 DDL 又有对 DB2 内嵌 SQLJ 存储过程的调用。

清单 1. DDL 和 SQLJ 存储过程语句示例

-- -- connect to the &database
connect to &database user &user using &password;
-- -- install Stored Procedure
DROP PROCEDURE DB2TOOL.CALLDB2ADVIS;
CALL SQLJ.REMOVE_JAR ('DB2TOOL.CALLDB2ADVIS');
CALL SQLJ.REFRESH_CLASSES();
CALL SQLJ.INSTALL_JAR('file:/home/luwsp.jar', 'DB2TOOL.CALLDB2ADVIS');------------- ①
CALL SQLJ.REFRESH_CLASSES();
-- -- create Stored Procedure
CREATE PROCEDURE DB2TOOL.CALLDB2ADVIS ( INOUT major_version INTEGER,
         INOUT minor_version INTEGER,
         IN requested_locale VARCHAR(33),
         IN xml_input BLOB(32M),
         IN xml_filter BLOB(4K),
         OUT xml_output BLOB(4K),
         OUT xml_message BLOB(64K) )
DYNAMIC RESULT SETS 3
NOT DETERMINISTIC
LANGUAGE Java
EXTERNAL NAME 'DB2TOOL.CALLDB2ADVIS:com.ibm.datatools.ia.luw.CALLDB2ADVIS.cALLDB2ADVIS'
FENCED
THREADSAFE
PARAMETER STYLE JAVA;      --------------------- ②
-- -- grant the execution privilege to public    
GRANT EXECUTE ON PROCEDURE DB2TOOL.CALLDB2ADVIS TO PUBLIC WITH GRANT OPTION;
connect reset;
terminate;

在上面的 SQL 语句中,语句之间的依赖性很强。例如,如果语句①不能正确执行,直接影响到语句②的执行,因为它们之前存在着引用关系。针对这种情况的 Java 数据库交互编程,通常采用将这些语句封装成一个数据库 SQL 脚本文件去执行,主要执行过程如下:
准备数据库脚本文件的执行环境,主要是对一些环境变量的设置;
运行数据库脚本文件,把输出结果定向到特定的文件;
Java 程序系统的分析数据库脚本文件的输出结果,得到每一条 SQL 的运行状况;
清除数据库脚本文件的执行环境,还原到初始状态。
这种运行 DDL 和 SQLJ 存储过程的方法,存在着以下几个缺点:
依赖数据库环境。需要在过程的开始阶段,对脚本文件的执行环境进行初始化,在脚本文件运行结束后,必须对环境进行清除;
难以对执行过程进行控制。例如在清单 1 中的 SQL 语句执行过程中,如果语句①执行失败,脚本文件不会终止运行并把错误信息发送给 Java 程序,而会继续执行下一条 SQL 语句,这时可以确定语句②必定执行失败,但是脚本文件还是强制执行语句②;
脚本文件的输出结果难以处理。由于 SQL 语句在不同的数据库环境下,输出结果的格式信息有所变化,这就极大的影响了 Java 程序读取输出结果的准确性,难以精确的定位到出现问题的 SQL 语句;
本文针对执行 DDL 和 SQLJ 存储过程数据库脚本文件引出的这些缺点,提出了利用 Java JDBC 执行 DDL 和 SQLJ 存储过程的方法。方法的一些简单示例代码如下。

清单 2. 简单的示例代码

Driver dbDriver=(Driver)Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance();
        String url="jdbc:db2://"+host+":"+port+"/"+database+"";
        Properties p = new Properties();
        p.put("user", username);
        p.put("password",password);
        conn= dbDriver.connect(url,p);
    try{
        stat=conn.createStatement();
        stat.executeUpdate(“DROP PROCEDURE DB2TOOL.CALLDB2ADVIS”);
        stmt = conn.prepareCall(“CALL SQLJ.REFRESH_CLASSES()”);
        stmt.execute();        &nbs