您最多能選擇 25 個主題 主題必須以字母或數字為開頭,可包含連接號「-」且最長為 35 個字元。
 
 
 
 

177 行
5.6 KiB

/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.utils;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.jdbc.support.JdbcUtils;
import com.bstek.ureport.definition.dataset.Field;
import com.bstek.ureport.exception.ReportException;
/**
* @author Jacky.gao
* @since 2017年12月27日
*/
public class ProcedureUtils {
public static boolean isProcedure(String sql){
sql=sql.trim().toLowerCase();
return sql.startsWith("call ");
}
public static List<Field> procedureColumnsQuery(String sql,Map<String, Object> pmap,Connection conn){
StatementWrapper wrapper=buildProcedureCallableStatement(sql, pmap, conn);
CallableStatement cs=wrapper.getCallableStatement();
int oracleCursorIndex=wrapper.getOracleCursorIndex();
ResultSet rs=null;
try {
if(oracleCursorIndex==-1){
rs=cs.executeQuery();
}else{
cs.executeUpdate();
rs=(ResultSet)cs.getObject(oracleCursorIndex);
}
ResultSetMetaData metadata=rs.getMetaData();
int columnCount=metadata.getColumnCount();
List<Field> fields=new ArrayList<Field>();
for(int i=1;i<=columnCount;i++){
String columnName=metadata.getColumnLabel(i);
fields.add(new Field(columnName));
}
return fields;
} catch (SQLException e) {
throw new ReportException(e);
}finally{
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(cs);
JdbcUtils.closeConnection(conn);
}
}
public static List<Map<String,Object>> procedureQuery(String sql,Map<String, Object> pmap,Connection conn){
StatementWrapper wrapper=buildProcedureCallableStatement(sql, pmap, conn);
CallableStatement cs=wrapper.getCallableStatement();
int oracleCursorIndex=wrapper.getOracleCursorIndex();
ResultSet rs=null;
try {
if(oracleCursorIndex==-1){
rs=cs.executeQuery();
}else{
cs.executeUpdate();
rs=(ResultSet)cs.getObject(oracleCursorIndex);
}
ResultSetMetaData metadata=rs.getMetaData();
int columnCount=metadata.getColumnCount();
List<Map<String,Object>> result=new ArrayList<Map<String,Object>>();
while(rs.next()){
Map<String,Object> map=new HashMap<String,Object>();
for(int i=1;i<=columnCount;i++){
String columnName=metadata.getColumnLabel(i);
map.put(columnName, rs.getObject(columnName));
}
result.add(map);
}
return result;
} catch (SQLException e) {
throw new ReportException(e);
}finally{
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(cs);
JdbcUtils.closeConnection(conn);
}
}
private static StatementWrapper buildProcedureCallableStatement(String sql,Map<String, Object> pmap,Connection conn){
try {
Map<String,Object> paramMap=new LinkedHashMap<String,Object>();
int leftParnPos=sql.indexOf("(");
int rightParnPos=sql.indexOf(")");
String paramStr="";
if(leftParnPos>-1 && rightParnPos>-1){
paramStr=sql.substring(leftParnPos+1,rightParnPos);
}
int oracleCursorIndex=-1,paramIndex=0;
String[] str=paramStr.split(",");
for(String param:str){
paramIndex++;
param=param.trim();
if(param.toLowerCase().equals("oracle")){
sql=sql.replaceFirst(param, "?");
oracleCursorIndex=paramIndex;
continue;
}else if(!param.startsWith(":")){
continue;
}
sql=sql.replaceFirst(param, "?");
String paramName=param.substring(1,param.length());
Object paramValue=pmap.get(paramName);
paramMap.put(paramName, (paramValue==null ? "" : paramValue));
}
String procedure="{"+sql+"}";
CallableStatement cs= conn.prepareCall(procedure);
int index=1;
for(String name:paramMap.keySet()){
Object value=paramMap.get(name);
if(value instanceof String){
cs.setString(index,(String)value);
}else if(value instanceof Date){
Date date=(Date)value;
cs.setDate(index, new java.sql.Date(date.getTime()));
}else if(value instanceof Integer){
cs.setInt(index, (Integer)value);
}else if(value instanceof Float){
cs.setFloat(index, (Float)value);
}else if(value instanceof Double){
cs.setDouble(index, (Double)value);
}else{
cs.setObject(index, value);
}
index++;
}
if(oracleCursorIndex>-1){
cs.registerOutParameter(oracleCursorIndex, -10);
}
return new StatementWrapper(cs,oracleCursorIndex);
} catch (SQLException e) {
throw new ReportException(e);
}
}
}
class StatementWrapper{
private CallableStatement callableStatement;
private int oracleCursorIndex;
public StatementWrapper(CallableStatement callableStatement,int oracleCursorIndex) {
this.callableStatement=callableStatement;
this.oracleCursorIndex=oracleCursorIndex;
}
public CallableStatement getCallableStatement() {
return callableStatement;
}
public int getOracleCursorIndex() {
return oracleCursorIndex;
}
}