Chinaunix首页 | 论坛 | 博客
  • 博客访问: 92240281
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: Oracle

2008-04-12 16:37:03

 来源:赛迪网技术社区    作者:softprog

使用 Oracle 特有的 SQL 语句

Spring 框架的一个有用的特点是它仅专注于“包装”JDBC 开发的最常用和最麻烦的方面,而不会过度阻止在需要的时候使用专有的 SQL/JDBC。虽然我们都希望使我们的代码完全标准化(如果这样做对我们无任何影响或有些一定影响),但有很多时候使用特殊的供应商特有的特性将是谨慎甚至必须的做法。

在 Oracle 范畴中的一个示例就是使用 Oracle 的 ROWID 来唯一描述 Oracle 表中的行。代码清单 7 和 8 显示了传统的基于 JDBC 和 Spring 的 JDBC 代码,它们分别根据提供的员工号从 scott/tiger EMP 表中检索 ROWID。在两种情况下都提供了一个作为字符串返回的 ROWID。

代码清单 7

String queryStr = "SELECT rowid FROM emp 
WHERE empno = "+ aEmpNum; 
// aEmpNum set previouslyString rowId = null;
try{stmt = this.myConnection.createStatement();
rs = stmt.executeQuery(queryStr);while ( rs.next() ) 
{rowId = rs.getString("ROWID"); }} 
// lots of catch-finally code needed after this

代码清单 8

String queryStr = "SELECT rowid FROM emp 
WHERE empno = "+ aEmpNum;String rowId = null; 
try{JdbcTemplate jt = new JdbcTemplate(this.myDataSource);
oracle.sql.ROWID oraRowId =(ROWID) jt.queryForObject(queryStr, ROWID.class);
rowId = oraRowId.stringValue();}
catch ( IncorrectResultSizeDataAccessException wrongSizeEx )
{// This unchecked exception is thrown in this case if more
// than one result is returned from the query.
// Explicitly printing out the results of this exception's
// methods getExpectedSize() and getActualSize() is really not
// necessary in this case because this exception's getMessage()
// returns this same information in sentence form. System.err.println( wrongSizeEx.getMessage() );
System.err.print
( "Expected " + wrongSizeEx.getExpectedSize()+ " results,
 but actually got back "+ wrongSizeEx.getActualSize() + " results.");}

除了显示 Spring 框架支持 Oracle 特有的关键字的灵活性之外,代码清单 8 还显示了 Spring 的 DAO 异常之一的用途。在代码清单 8 中,如果不小心编辑了 queryStr 来返回所有的 ROWID,那么将抛出 IncorrectResultSizeDataAccessException。

专有 Oracle SQL 的最为大家所熟悉的例子可能是无处不在的查询 SELECT sysdate FROM dual。代码清单 9 显示了这个 Oracle 特有的查询(不是 ANSI 标准的一部分)如何与 Spring 框架一起使用。

代码清单 9

String queryStr = "SELECT sysdate FROM dual";
Date date = null;
 try{JdbcTemplate jt = new JdbcTemplate(this.myDataSource);
date = (Date) jt.queryForObject(queryStr, Date.class);}
catch ( BadSqlGrammarException badSqlEx ) 
// unchecked{System.err.println( badSqlEx.getMessage() );
System.err.println( "Bad SQL:" + badSqlEx.getSql() );}

DDL 语句与 Spring 和 JDBC

前面的代码代码清单演示了使用 Spring 框架来处理 DML 语句。Spring 框架提供了非常简单的语义来支持 DDL 语句。代码清单 10 和 11 演示了用来执行从 Oracle 数据库中删除和清除表的语句的标准 JDBC 代码和 Spring 包装的 JDBC 代码。

代码清单 10

Statement stmt = null;
try{stmt = this.myConnection.createStatement();
stmt.executeUpdate("DROP TABLE salgrade PURGE");
}catch ( SQLException sqlEx )
{System.err.println("Message:" + sqlEx.getMessage());
System.err.println("Error Code:" + sqlEx.getErrorCode());
System.err.println("SQL State:" + sqlEx.getSQLState());}
finally{try {if (stmt != null)  
 {stmt.close();   } }catch (SQLException finallySqlEx) 
// checked exception {System.err.println(finallySqlEx.getMessage()); 
}
}

代码清单 11

try{JdbcTemplate jt = new JdbcTemplate(this.myDataSource);
jt.execute("DROP TABLE salgrade PURGE");
}
catch ( BadSqlGrammarException badSqlEx ) 
// unchecked{System.err.println( badSqlEx.getMessage() );
System.err.println( "BadSQL:" + badSqlEx.getSql() );}

这时应该很明显,基于 Spring 的代码比直接的 JDBC 代码要更易于阅读(以及编写和维护)。实际上,这个代码清单中只有两行是绝对必需的,因为捕获的异常是一个非强制异常。

利用 Spring 框架访问存储过程

代码清单 13 和 14 分别演示了从直接的 JDBC 和 Spring 包装的 JDBC 来访问一个经过设计的存储过程(如代码清单 12 所示)。

代码清单 12

CREATE OR REPLACE PROCEDURE 
salary_percentile 
(salary IN emp.sal%TYPE,
low IN salgrade.losal%TYPE,high 
IN salgrade.hisal%TYPE,percentile OUT NUMBER )
ASBEGINIF salary < 0 THENpercentile := null;
ELSEpercentile := (salary - low) / (high - low);END IF;END;

代码清单 13

String escapeString = "{call salary_percentile (?,?,?,?)}"
;CallableStatement cStmt = null;
double percentile = -1.0;final int PERCENTILE_INDEX = 4;
   try{cStmt = this.myConnection.prepareCall(escapeString);
cStmt.setInt(1, aSalary);
 // aSalary passed into this methodcStmt.setInt(2, aLow); 
  // aLow passed into this methodcStmt.setInt(3, aHigh);
 // aHigh passed into this methodcStmt.registerOutParameter
(PERCENTILE_INDEX, Types.DOUBLE);cStmt.execute();
percentile = cStmt.getDouble(PERCENTILE_INDEX);}
catch ( SQLException sqlEx )
{System.err.println("Message:" + sqlEx.getMessage());
System.err.println("Error Code:" + sqlEx.getErrorCode());
System.err.println("SQL State:" + sqlEx.getSQLState());}
finally{if ( cStmt != null ) {try   {cStmt.close();
   }catch (SQLException finallySqlEx) 
  {System.err.println(finallySqlEx.getMessage());
   } }}return percentile;
阅读(310) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~