/******************************************************************************* * Copyright (c) 2013 hangum. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * hangum - initial API and implementation ******************************************************************************/ package com.hangum.tadpole.engine.sql.util.executer.procedure; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import com.hangum.tadpole.engine.manager.TadpoleSQLManager; import com.hangum.tadpole.engine.query.dao.mysql.ProcedureFunctionDAO; import com.hangum.tadpole.engine.query.dao.rdb.InOutParameterDAO; import com.hangum.tadpole.engine.query.dao.system.UserDBDAO; import com.hangum.tadpole.engine.sql.util.OracleDbmsOutputUtil; import com.hangum.tadpole.engine.sql.util.RDBTypeToJavaTypeUtils; import com.hangum.tadpole.engine.sql.util.resultset.TadpoleResultSet; /** * oracle procedure executer * * <pre> * * Procedure sample.... CREATE OR REPLACE PROCEDURE p_add (rowcnt IN INT ,retcode OUT INT ,retmsg OUT VARCHAR2 ,cursorParam OUT SYS_REFCURSOR) IS BEGIN OPEN cursorParam FOR SELECT table_name FROM user_tables WHERE ROWNUM <= rowcnt; retcode := SQLCODE; retmsg := SQLERRM; END; </pre> * * @author hangum * @author nilriri * */ public class OracleProcedureExecuter extends ProcedureExecutor { /** * Logger for this class */ private static final Logger logger = Logger.getLogger(OracleProcedureExecuter.class); /** * * @param procedureDAO * @param userDB */ public OracleProcedureExecuter(ProcedureFunctionDAO procedureDAO, UserDBDAO userDB) { super(procedureDAO, userDB); } @Override public boolean exec(final List<InOutParameterDAO> parameterList) throws Exception { initResult(); java.sql.Connection javaConn = null; java.sql.CallableStatement cstmt = null; java.sql.PreparedStatement pstmt = null; ResultSet rs = null; OracleDbmsOutputUtil dbmsOutput = null; try { if(listOutParamValues == null) getOutParameters(); javaConn = TadpoleSQLManager.getConnection(userDB); try { dbmsOutput = new OracleDbmsOutputUtil( javaConn ); dbmsOutput.enable(1000000); } catch(SQLException e) { logger.error("dbmsoutput exception", e); } // make the script String strExecuteScript = getMakeExecuteScript(); if (StringUtils.startsWithIgnoreCase(strExecuteScript, "SELECT")){ // function execute... pstmt = javaConn.prepareStatement(strExecuteScript); for (InOutParameterDAO inOutParameterDAO : parameterList) { pstmt.setObject(inOutParameterDAO.getOrder(), inOutParameterDAO.getValue()); } // Set the OUT Parameter for (int i = 0; i < listOutParamValues.size(); i++) { InOutParameterDAO dao = listOutParamValues.get(i); //pstmt.registerOutParameter(dao.getOrder(), RDBTypeToJavaTypeUtils.getJavaType(dao.getRdbType())); pstmt.setObject(dao.getOrder(), ""); } rs = pstmt.executeQuery(); setResultCursor(strExecuteScript, rs); }else{ // set prepare call cstmt = javaConn.prepareCall(strExecuteScript); // Set input value for (InOutParameterDAO inOutParameterDAO : parameterList) { cstmt.setObject(inOutParameterDAO.getOrder(), inOutParameterDAO.getValue()); } // Set the OUT Parameter for (int i = 0; i < listOutParamValues.size(); i++) { InOutParameterDAO dao = listOutParamValues.get(i); if(logger.isDebugEnabled()) logger.debug("Out Parameter " + dao.getOrder() + " JavaType is " + RDBTypeToJavaTypeUtils.getJavaType(dao.getRdbType())); cstmt.registerOutParameter(dao.getOrder(), RDBTypeToJavaTypeUtils.getJavaType(dao.getRdbType())); } cstmt.execute(); // // 결과 set // // 결과가 cursor가 아닌경우 결과를 담기위한 list // boolean is cursor boolean isCursor = false; for (int i = 0; i < listOutParamValues.size(); i++) { InOutParameterDAO dao = listOutParamValues.get(i); if(logger.isDebugEnabled()) logger.debug("Execute Procedure result " + dao.getName() + "=" + cstmt.getString(dao.getOrder())); Object obj = cstmt.getObject(dao.getOrder()); // 실행결과가 String이 아닌경우 Type Cast가 필요함.... 현재는 무조건 String 으로... if (obj!=null){ if ("SYS_REFCURSOR".equals(dao.getRdbType())){ isCursor = true; rs = (ResultSet)obj; setResultCursor(strExecuteScript, rs); // cursor의 결과 리턴은 항상 1개입니다. }else{ dao.setValue(obj.toString()); } } } if(!isCursor) { List<Map<Integer, Object>> sourceDataList = new ArrayList<Map<Integer,Object>>(); Map<Integer, Object> tmpRow = null; for (int i = 0; i < listOutParamValues.size(); i++) { InOutParameterDAO dao = listOutParamValues.get(i); tmpRow = new HashMap<Integer, Object>(); tmpRow.put(0, ""+dao.getOrder()); tmpRow.put(1, ""+dao.getName()); tmpRow.put(2, ""+dao.getType()); tmpRow.put(3, ""+dao.getRdbType()); tmpRow.put(4, ""+dao.getLength()); tmpRow.put(5, ""+dao.getValue()); sourceDataList.add(tmpRow); } setResultNoCursor(strExecuteScript, new TadpoleResultSet(sourceDataList)); } } try { dbmsOutput.show(); } catch(SQLException e) { logger.error("dbmsoutput exception", e); } setStrOutput(dbmsOutput.getOutput()); return true; } catch (Exception e) { logger.error("ProcedureExecutor executing error", e); throw e; } finally { try { if(rs != null) rs.close(); } catch (Exception e) { } try { if(pstmt != null) pstmt.close(); } catch (Exception e) { } try { if(cstmt != null) cstmt.close(); } catch (Exception e) { } try { if(dbmsOutput != null) dbmsOutput.close(); } catch (Exception e) { } try { if(javaConn != null) javaConn.close(); } catch (Exception e) { } } } }