[Java]通过Jdbc调用存储过程

这篇博客介绍了如何使用Java的JdbcTemplate调用Oracle存储过程,包括处理有返回结果集和无返回结果集的情况。通过示例展示了存储过程的调用方式以及如何获取和操作返回的结果集。

1.sql语句:call storeProcedure(a,b,c)

 

2.存储过程有返回结果集或结果做法:

Connection conn = null;
		CallableStatement cs = null;
		ResultSet rs = null;
		try {
			conn = jdbcTemplate.getDataSource().getConnection();
			cs = conn.prepareCall(sqlLibrary.EventLog_listEventLogByAppIdNStatus);
			conn.setAutoCommit(false);
			cs.setString(1, app_flag);
			cs.setString(2, status);
			cs.setString(3, eventMaxCount);
			cs.registerOutParameter(4, OracleTypes.CURSOR);
			cs.execute();
			rs = (ResultSet) cs.getObject(4);
			while (rs.next()) {
				event_list.add(new Event(rs));
			}
			rs.close();
			conn.commit();
			conn.setAutoCommit(true);
		} catch (SQLException e) {
			logger.error("sql exception: " + e.getMessage()); ///
		} catch (DataAccessException e) {
			dbLogger.error("One PNS DB is down. Exception: " + e.getMessage());
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (cs != null)
					cs.close();
				if (conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

 可以看到这是存储过程(Oracle)有返回结果集的,output是一个cursor

ResultSet:

public Event(ResultSet rs) throws SQLException{
		this.event_id = rs.getString("event_id");
		this.user_id = rs.getString("user_id");
		this.msisdn = rs.getString("msisdn");
		this.service_name  = rs.getString("service_name");
		this.quota_status = rs.getString("quota_status");
		this.quota_name = rs.getString("quota_name");
		this.event_code = rs.getString("event_code");
		this.app_flag = rs.getInt("app_flag");
		this.status = rs.getInt("status");
		this.event_date =  getOracleTimestamp(rs.getObject("event_date"));
		this.last_update_date =  getOracleTimestamp(rs.getObject("last_update_date"));
		this.event_content = rs.getString("event_content");
	}

 

 

3.没有返回结果集的

Connection conn = null;
		CallableStatement cs = null;
		ResultSet rs = null;
		int rs_code = 99;
		String rs_msg = null;
		List<CsvModel> searchResultList = new ArrayList<CsvModel>();
		try{
			conn = jdbcTemplate.getDataSource().getConnection();
			cs = conn.prepareCall(Constant.UMGCsvStoreProcedure_call);
			logger.debug("=======param in:{}", csvSP.toString());
			cs.setString(1, csvSP.getSubmitTimeFro());
			cs.setString(2, csvSP.getSubmitTimeTo());
			/*cs.setTimestamp(1, Timestamp.valueOf(csvSP.getSubmitTimeFro()));
			cs.setTimestamp(2, Timestamp.valueOf(csvSP.getSubmitTimeTo()));*/
			cs.setString(3, csvSP.getCorpId());
			cs.setString(4, csvSP.getSenderList());
			cs.setString(5, csvSP.getRecipientList());
			cs.setString(6, csvSP.getChannel());
			cs.setString(7, csvSP.getDirection());
			cs.setString(8, null);
			cs.setString(9, null);
			cs.registerOutParameter(10, Types.INTEGER);
			cs.registerOutParameter(11, Types.VARCHAR);
			cs.execute();
			rs = cs.getResultSet();
			
			rs_code = (int) cs.getObject(10);
			rs_msg = (String) cs.getObject(11);
			if (rs_code == 0) {
				while (rs.next()) {
					searchResultList.add(new CsvModel(rs));
				}
			}
			rs.close();
		}catch (DataAccessException e) {
			dbLogger.error("DB is down. Exception is [{}]", e.getMessage());
			throw e;
		} catch (SQLException e) {
			logger.error("-- Error occur, exception is [{}]", e.getMessage());
			e.printStackTrace();
		}catch (Exception e) {
			logger.error("-- Error occur, exception is [{}]", e.getMessage());
			throw e;
		}finally {
			try {
				if (rs != null)
					rs.close();
				if (cs != null)
					cs.close();
				if (conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

可以看出,基本是和有结果集的操作差不多,但由于我的select statement不是以结果集游标的形式返回,所以要用上getResultSet()来获得.

 

参考:

1.JdbcTemplate执行存储过程的3种方式:https://blog.youkuaiyun.com/jiaweicheng77/article/details/84564092

2.Using Unbounded SELECT Statements:https://learning.oreilly.com/library/view/mysql-stored-procedure/0596100892/ch05s04.html

注意,以下使用数据库为sql2000,驱动jtds1.2.2 一、调用存储过程(无结果集返回) Connection connection = ConnectionHelper.getConnection(); CallableStatement callableStatement = connection.prepareCall("{ call procedureName(?,?) }"); callableStatement.setString(1, "xxxxxxxx"); callableStatement.setString(2, "xxxxxxxx"); callableStatement.execute(); //获得sql的消息并输出,这个估计很多人都需要 SQLWarning sqlWarning = callableStatement.getWarnings(); while (sqlWarning != null) { System.out.println("sqlWarning.getErrorCode() = " + sqlWarning.getErrorCode()); System.out.println("sqlWarning.getSQLState() = " + sqlWarning.getSQLState()); System.out.println("sqlWarning.getMessage() = " + sqlWarning.getMessage()); sqlWarning = sqlWarning.getNextWarning(); } //close ConnectionHelper.closeConnection(callableStatement, connection); 二、调用存储过程,返回sql类型数据(非记录集) Connection connection = ConnectionHelper.getConnection(); CallableStatement callableStatement = connection.prepareCall("{ call procedureName(?,?,?) }"); callableStatement.setString(1, "xxxxxxxx"); callableStatement.setString(2, "xxxxxxxx"); //重点是这句1 callableStatement.registerOutParameter(3, Types.INTEGER); callableStatement.execute(); //取返回结果,重点是这句2 //int rsCount = callableStatement.getInt(3); //close ConnectionHelper.closeConnection(callableStatement, connection); 三、重点来了,返回记录集,多记录集 注意,不需要注册返回结果参数,只需要在sql中select出结果即可 例如:select * from tableName 即可得到返回结果 Connection connection = ConnectionHelper.getConnection(); CallableStatement callableStatement = connection.prepareCall("{ call procedureName(?) }"); //此处参数与结果集返回没有关系 callableStatement.setString(1, "xxxxxxxx"); callableStatement.execute(); ResultSet resultSet = callableStatement.getResultSet(); //以上两个语句,可以使用ResultSet resultSet = callableStatement.executeQuery();替代 //多结果返回 ResultSet resultSet2; if (callableStatement.getMoreResults()) { resultSet2 = callableStatement.getResultSet(); while (resultSet2.next()) { } } //close ConnectionHelper.closeConnection(callableStatement, connection); 提示:多结果返回可以使用如下代码(以上主要让大家明白,单一结果和多结果的区别): Boolean hasMoreResult = true; while (hasMoreResult) { ResultSet resultSet = callableStatement.getResultSet(); while (resultSet.next()) { } hasMoreResult = callableStatement.getMoreResults(); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值