« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
| 公告 |
戒除浮躁,读好书,交益友 |
Blog信息 |
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9691964 建立时间:2004年12月20日 |

| |
[数据库]java 存取sybase的例子 文章收藏, 网上资源, 电脑与网络
邢红瑞 发表于 2005/4/24 19:30:20 |
很难找到的,所有收藏一下。第一个
SQL: create proc test as select name into #tmp from sysobjects where type='U' select * from #tmp return (55) go JAVA: String tsql = "{ ?=call test }"; CallableStatement stmt = con.prepareCall(tsql); stmt.registerOutParameter(1,java.sql.Types.INTEGER); ResultSet rs = stmt.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int columns = rsmd.getColumnCount(); //获得#tmp结果集 while(rs.next()) { for(int i=1;i<=columns;i++) { System.out.print(rs.getString(i)+'\t'); } } int o = stmt.getInt(1);//获得存储过程返回结果55
第二个 spring的IF OBJECT_ID('dbo.sp_xx') IS NOT NULL BEGIN DROP PROCEDURE dbo.sp_xx IF OBJECT_ID('dbo.sp_xx') IS NOT NULL PRINT '<<< FAILED DROPPING PROCEDURE dbo.sp_xx >>>' ELSE PRINT '<<< DROPPED PROCEDURE dbo.sp_xx >>>' END go create proc sp_xx ( @userid int) as begin select personid, personname from person where personid = @userid select teamid, teamname from team end EXEC sp_procxmode 'dbo.sp_xx','unchained' go private class ProcWithResultSet extends StoredProcedure { public ProcWithResultSet(DataSource dataSource) { setDataSource(dataSource); setSql("sp_xx"); //declareParameter(new SqlParameter("userid", java.sql.Types.INTEGER)); //(1) //declare the first out param in the sp, the name rsPerson is the key of result map declareParameter(new SqlReturnResultSet("rsPerson", new PersonRowMapper())); //declare the second out param in the sp, the name rsTeam is the key of result map declareParameter(new SqlReturnResultSet("rsTeam", new TeamRowMapper())); //declare input params, the name userid is the IN params of the param declareParameter(new SqlParameter("userid", java.sql.Types.INTEGER)); //(2) compile(); } public Map getRsFromSP(int userID) { Map map = new HashMap(); map.put("userid", new Integer(userID)); return execute(map); } } private class PersonRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { UserInfo u = new UserInfo(); u.setPersonID(rs.getInt(1)); u.setUserName(rs.getString(2)); return u; } } private class TeamRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new PropertyValue(rs.getInt(1)+"", rs.getString(2)); } }
Spring中对于jdbc 调用带有返回结果集的存储过程是用的这个方法。 Java代码 /** * Extract returned ResultSets from the completed stored procedure. * @param cs JDBC wrapper for the stored procedure * @param parameters Parameter list for the stored procedure * @return Map that contains returned results */ protected Map extractReturnedResultSets(CallableStatement cs, List parameters, int updateCount) throws SQLException { Map returnedResults = new HashMap(); int rsIndex = 0; boolean moreResults; do { if (updateCount == -1) { //(3) Object param = null; if (parameters != null && parameters.size() > rsIndex) { param = parameters.get(rsIndex); //(4) } if (param instanceof SqlReturnResultSet) { SqlReturnResultSet rsParam = (SqlReturnResultSet) param; returnedResults.putAll(processResultSet(cs.getResultSet(), rsParam)); //(5) } else { logger.warn("Results returned from stored procedure but a corresponding " + "SqlOutParameter/SqlReturnResultSet parameter was not declared"); } rsIndex++; } moreResults = cs.getMoreResults(); //(6) updateCount = cs.getUpdateCount(); if (logger.isDebugEnabled()) { logger.debug("CallableStatement.getUpdateCount() returned " + updateCount); } } while (moreResults || updateCount != -1); return returnedResults; }
原因分析: 1:Sybase不支持Out 参数返回结果集。只能再Sp当中最后select column from some table 2:Sybase的JDBC Driver对于jdbc的实现比较令人费解,如果一个Sp返回多个结果集,如果不调用第一个结果集即statement.getResultSet() 那么接下来statementcs.getMoreResults()会返回False,即使有有第二个返回结果集,它一样返回false,那么Spring就会把返回结果认为是一个update的 结果,就不会对其它结果集进行处理。 3:Spring中如果jdbc返回结果集,那么程序会执行到(3)处,这里rsIndex = 0,如果输入参数声明在先,那么这里得到的将会是输入参数, (5)处的cs.getResultSet()将不会被执行,第一个ResultSet不会被处理,同时,因为(5)处没有被执行,那么(6)处会返回false,也就是解下来 的结果集不会被正确的认出来,Spring也不会去处理后续的结果集,这样就一个结果集也得不到了。 4:这里主要还是Sybase jdbcDriver在实现jdbc时有bug,但是我们只能顺着人家来,在用Spring Jdbctemplate调用时注意一下了。
3 多个记录集 与oracle不同
try{String sql = "{ call sp_select_role_priv ( ? ) } " ;
dbm = DBConnectionPool.getInstance();conn = dbm.getConnection(Constants.DB_earn) ;cstmt = (SybCallableStatement) conn.prepareCall(sql) ;java.sql.ResultSet rset = null ; //得到的结果集java.sql.ResultSet rs = null ; //小结果集
do{rs = cstmt.getResultSet() ;System.out.println("## resultSet:"+k);while (rs.next()) {if(k==1){ if(rs.getInt(1)%26lt;1){continue;}}if(k==2){if(rs.getInt(1)%26lt;0){ //1:具有权限continue;}}} rs.close() ;k++;}while (cstmt.getMoreResults());
}catch (SQLException ex) {ex.printStackTrace() ;}finally {........}
结果执行,成功的将问题解决.sybase和oracle有所不同的是,它取得第几个结果集的时候是通过rs = cstmt.getResultSet()得到的,在得到这个结果集这前,需要将游标指到应该得到的地方,可以通过cstmt.getMoreResults(int i)得到,也可以以次取,通过cstmt.getMoreResults()将游标指向下一个结果集.
另外,自己又看了一下java.sql包中的类,和SybCallableStatement,发现,直接调用java.sql包的中CallableStatement,也有getMoreResults()方法,那么这些驱动有两种可能,一种是实现自己的读取方法,二是针对数据库自身的特性,进行了效率上的提高. |
|
|