/**
 * Title:        数据库语句执行类
 * Company:      泛微软件
 * @author:      刘煜
 * @version:     1.0
 * create date : 2001-10-23
 * modify log: 
 *
 *
 * Description:  采用 java.sql 中的 CallableStatement 和 Statement 执行数据库操作。
 *               客户端直接调用该类进行数据库操作。不需要考虑数据库链接的建立.
 *
 *               客户端指所有调用该类进行数据库操作的应用程序，不特指用户的客户端。
 *
 *               RecordSet 执行数据库操作有两种形式，一种为调用存储过程，另一种为直接执行SQL语句
 *               与ConnStatement不同 ，RecordSet 执行SQL语句不分查询和修改，都在一条语句中执行
 *               1、使用默认的链接池执行SQL语句：   
 *                  RecordSet rs = new RecordSet() ;
 *	                rs.executeSql(" select * from TB_Example ") ;
 *	                while( rs.next() ) {
 *                      String thename = rs.getString("name") ;
 *                      ......
 *                  }
 *               2、使用指定的链接池ecologytest执行SQL语句
 *                  RecordSet rs = new RecordSet() ;
 *	                rs.executeSql(" update TB_Example set name = 'the new value' " , "ecologytest" ) ;
 *
 *               3、使用指定的链接池ecologytest执行存储过程 PD_Example_UpdateById
 *                   存储过程PD_Example_UpdateById：
 *                   CREATE  PROCEDURE [PD_Example_UpdateById]
 *                       (@name	varchar(100),
 *                        @id	int,
 *                        @flag integer output,
 *                        @msg varchar(80) output)
 *                   AS
 *                       update TB_Example set name = @name where id = @id
 *
 *                   GO
 *
 *
 *                   RecordSet rs = new RecordSet() ;
 *
 *                   String newname = ....... ;
 *                   String id = ...... ;
 *                   String procpara = newname + Util.getSeparator() + id ;
 *	                 rs.executeProc( "PD_Example_UpdateById" , procpara , "ecologytest" ) ;
 *
 *                   procpara 是存储过程的参数值组成的字符串变量，
 *                   多个参数值之间用 weaver.general.Util.getSeparator() 分开
 *
 *               4、在一个客户程序多个执行之间，查询结果可以保留到下一次查询 
 *                  RecordSet rs = new RecordSet() ;
 *	                rs.executeSql(" select * from TB_Example ") ;
 *                  rs.executeSql(" update TB_Example set name = 'the new value '") ;
 *	                while( rs.next() ) {
 *                      String thename = rs.getString("name") ;  //得到修改前查询的值
 *                      ......
 *                  }
 *                  rs.executeSql(" select * from TB_Example ") ;
 *                  while( rs.next() ) {
 *                      String thename = rs.getString("name") ;  //得到修改后查询的值
 *                      ......
 *                  }
 *
 *
 */




package weaver.conn;


import com.api.integration.util.ProcBean;
import com.engine.common.biz.CheckSensitiveWordBiz;
import com.gbasedbt.jdbc.IfmxCallableStatement;
import com.gbasedbt.lang.IfxTypes;
import com.google.common.collect.Lists;

import oracle.jdbc.OracleTypes;
import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;

import org.apache.commons.lang3.StringUtils;

import weaver.conn.constant.DBConstant;
import weaver.conn.util.IdHandler;
import weaver.conn.util.ProcChecker;
import weaver.conn.util.ProcParamStore;
//import weaver.filter.EncyParam;
import weaver.general.BaseBean;
import weaver.general.GCONST;
import weaver.general.StringUtil;
import weaver.general.Util;
import weaver.interfaces.datasource.BaseDataSource;
import weaver.monitor.cache.CacheFactory;
import weaver.monitor.cache.ResultMap;
import weaver.monitor.cache.Util.ConfigMap;
import weaver.servicefiles.DataSourceXML;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.*;
import java.text.NumberFormat;
import java.util.*;
import java.util.Date;
import java.util.stream.Stream;
import weaver.encrypt.EncryptUtil;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang3.ArrayUtils;

public class
RecordSet extends BaseBean implements RecordSetExecutionInterface
{
    //当前使用的连接池名称
    private String poolname = null;

    private SqlParserUtil sqlParserUtil;

    private SqlParserUtilForSensitvie sqlParserUtilForSensitvie;


    /**
     * 存储不自动加密
     * @param noAutoEncrypt
     */
    public void setNoAutoEncrypt(boolean noAutoEncrypt){
        sqlParserUtil.setNoAutoEncrypt(noAutoEncrypt);
    }

    /**
     * 是否直接返回密文数据
     */
    private boolean isAutoDecrypt = true;
    public void isAutoDecrypt(boolean isAutoDecrypt){
        this.isAutoDecrypt = isAutoDecrypt;
    }

    /**
     * 脱敏数据是否返回明文
     */
    private boolean isReturnDecryptData = false;
    public void isReturnDecryptData(boolean isReturnDecryptData){
        this.isReturnDecryptData = isReturnDecryptData;
    }

//	//读写分离
//    public static String read_pool = "ecology_read";

//   	private String readDbDeal(String s, String poolname) {
//   		try{
//   		ReadDBService readDBService = new ReadDBService();
//   		 if(readDBService.isReadDb(s, poolname)){
//   			 String url = getPropValue(GCONST.getConfigFile() , read_pool + ".url"); 
//   			 if(StringUtils.isNotEmpty(url)){
//   				 poolname = read_pool;
//   				 this.writeLog("======readdb========="+s);
//   			 }
//   		 }
//   		}catch(Exception e){
//   			e.printStackTrace();
//   		}
//   		return poolname;
//   	}

    private String exceptionMsg = null;

    private boolean isEncrypt = true;

    public boolean isEncrypt() {
        return isEncrypt;
    }

    public void setEncrypt(boolean encrypt) {
        isEncrypt = encrypt;
        sqlParserUtil.setEncrypt(encrypt);
    }
    /**
     * 构造函数
     *
     */
    public RecordSet(boolean isEncrypt)
    {
        array = new Vector();
        bSuccess = true;
        checksql=true;
        sqlParserUtil = new SqlParserUtil(isEncrypt);
        sqlParserUtilForSensitvie = new SqlParserUtilForSensitvie();

    }

    public RecordSet()
    {
        array = new Vector();
        bSuccess = true;
        checksql=true;
        sqlParserUtil = new SqlParserUtil();
        sqlParserUtilForSensitvie = new SqlParserUtilForSensitvie();
    }

    protected RecordSet(String poolname)
    {
        array = new Vector();
        bSuccess = true;
        checksql = true;
        this.poolname = poolname;
        sqlParserUtil = new SqlParserUtil();
        sqlParserUtilForSensitvie = new SqlParserUtilForSensitvie();
    }


    /**
     * 执行存储过程，采用默认的链接池
     *
     * @param s    存储过程名称
     * @param s1   存储过程参数，多个参数中间用Util.getSeparator()分开
     *
     * @return boolean   如果执行成功，返回true，否则返回false
     */
    public boolean executeProc(String s, String s1)  {
        return executeProc(s, s1,null) ;
    }

    /**
     * 执行存储过程，采用指定的链接池
     *
     * @param s    存储过程名称
     * @param s1   存储过程参数，多个参数中间用Util.getSeparator()分开
     * @param poolname    指定的链接池名称，如果为null 则使用默认的链接池
     *
     * @return boolean   如果执行成功，返回true，否则返回false
     */
    public boolean executeProc(String s, String s1,String poolname)
    {
        parseArgument(s1);

        return executeProc(s, Lists.newArrayList(args), poolname);
    }

    public boolean executeProc(String s, List<String> arguments) {

        return executeProc(s, arguments, null);
    }

    public boolean executeProc(String s, List<String> arguments, String poolname) {
        if(!"".equals(s) && MonitorSqlUtil.getInstance().isIntercept(s)){
            new BaseBean().writeLog(s+"此sql不符合性能要求，已被拦截！");
            return false;
        }
        s=s.trim();
        //check if there is the class for this proc  @@@@@@@@@@@@@@@@@@@@@@@@@@
        ProcChecker procChecker = new ProcChecker(new ProcParamStore(s, poolname, this, args, true));
        if (procChecker.hasClass()) {
            try {
                procChecker.executeProc();
                bSuccess = true;
            } catch (Exception e) {
                setExceptionMsg(e.getMessage());
                bSuccess = false;
                writeLog(e);
            }

            return bSuccess;
        }

        this.sqlTmp = s;
        setExceptionMsg("");
        long l = 0L;
        long l2 = 0L;
        if(StringUtil.isEmpty(s)){
            setExceptionMsg("Query statement or procedure name is empty!");
            return false;
        }

        StringBuilder sb = new StringBuilder();
        /*
         * 取出缓存
         */
        ResultMap result = null;
        if(ConfigMap.get("iscache","").equals("1")){
            String s1= "";
            if(arguments != null){
                for(String tstr :arguments){
                    sb.append(tstr);
                }
                s1 = sb.toString();
                sb.delete(0,sb.length());
            }
            if(poolname == null || poolname.equals(GCONST.getServerName()) || poolname.equals(DataSourceXML.SYS_LOCAL_POOLNAME)){
                result = CacheFactory.getInstance().getRecordCacheForProc(s, s1);
                if(result != null && result.getArray() != null){
                    this.init();
                    CacheFactory.getInstance().convertMapToRS(result,this);
                    bSuccess = true ;
                    return true;
                }
            }
        }

        long time = System.currentTimeMillis();
        FastConnNode connNode = null;
        this.poolname = poolname;

        if(FastConnBuffer.isBuffered()){
            connNode = FastConnBuffer.getConnNode(poolname);
            if(connNode == null){
                if(!getConnection(poolname)){
                    setExceptionMsg("Failed to get database connection!");
                    return false;
                }

                connNode = new FastConnNode(conn, System.currentTimeMillis());
                FastConnBuffer.setConnNode(poolname, connNode);
            }else{

                conn = connNode.getConnection();

                if(System.currentTimeMillis() - connNode.getStartTime() > FastConnBuffer.RECONNECT_TIME){
                    //if(System.currentTimeMillis() - connNode.getStartTime() > 200){  // for test
                    try {
                        //System.out.println("~~~~~~~connect buffer recreate a new connection");  // for test
                        givebackConnection(poolname);
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    if(!getConnection(poolname)){
                        setExceptionMsg("Failed to get database connection!");
                        return false;
                    }

                    connNode = new FastConnNode(conn, System.currentTimeMillis());
                    FastConnBuffer.setConnNode(poolname, connNode);
                }
            }
            connNode.setExec(true);
        }else{
            if(!getConnection(poolname)){
                setExceptionMsg("Failed to get database connection!");
                return false;
            }
        }

        databaseType = conn.getDBType() ;
        String orgindbtype=conn.getOrgindbtype();
       // new BaseBean().writeLog("orgindbtype"+orgindbtype);
        boolean oldautocommit=true;//神通数据库必须把autocommit设置为false才能返回游标
        if (arguments == null) {
            arguments = Lists.newArrayList();
        }
        int i = arguments.size();
        for (int j = 0; j < i; j++) {
            sb.append(arguments.get(j));
            if (j < i - 1) {
                sb.append(separator);
            }
        }
        String arg_str = sb.toString();
        sb.delete(0, sb.length());

        try {
            if(orgindbtype.equals("st")||orgindbtype.equals("jc") || orgindbtype.equals("gs")||databaseType.equalsIgnoreCase("postgresql")){
                oldautocommit=conn.getAutoCommit();
                conn.setAutoCommit(false);
            }
            sb.append("{call ").append(s).append("(");
            int lastindex=0;
            if(databaseType.equals("db2")) {
                for(int j = 0; j < i ; j++) {
                    if(j==0) sb.append("?");
                    else sb.append(",?");
                }
                sb.append(")}").toString();
            }
//            else if(orgindbtype.equalsIgnoreCase("nt"))
//            {
//                for(int j = 0; j < i; j++)
//                    sb.append("?,");
////                lastindex=sb.lastIndexOf(",");
////                if(lastindex>0)
////                    sb.deleteCharAt(lastindex);
//                sb.append("?)}").toString();
//            }
            else {
                for(int j = 0; j < i + 1; j++)
                    sb.append("?,");
                if(databaseType.equals("oracle")||databaseType.equalsIgnoreCase("postgresql"))
                    sb.append("?,");
                sb.append("?)}").toString();
            }
            String s2 = sb.toString();
            sb.delete(0,sb.length());
            new BaseBean().writeLog(s2);
            CallableStatement callablestatement = conn.prepareCall(s2);
            if(orgindbtype.equalsIgnoreCase("nt"))
                callablestatement =(IfmxCallableStatement) conn.prepareCall(s2);
            for(int k = 0; k < i; k++)
            {
                //if(databaseType.equals("sqlserver")) args[k] = (new String(args[k].getBytes("UTF-8"),"ISO8859_1")) ;
                callablestatement.setString(k + 1, arguments.get(k));
                new BaseBean().writeLog("k"+k+"=====arguments=="+arguments.get(k));
            }

            if(!databaseType.equals("db2")) {
                if(orgindbtype.equals("jc") || orgindbtype.equalsIgnoreCase("gs")||databaseType.equalsIgnoreCase("postgresql")){
                    callablestatement.registerOutParameter(i + 1, Types.INTEGER);
                }
                else if(orgindbtype.equals("nt"))
                    callablestatement.registerOutParameter(i + 1, Types.INTEGER);
                else {
                    callablestatement.registerOutParameter(i + 1, Types.NUMERIC);
                }

                    callablestatement.registerOutParameter(i + 2, Types.VARCHAR);

                    if (orgindbtype.equals("jc") || orgindbtype.equals("gs") || databaseType.equalsIgnoreCase("postgresql")) {
                        callablestatement.registerOutParameter(i + 3, Types.REF_CURSOR);
                    }
                    else if(orgindbtype.equals("nt"))
                    {
                        callablestatement.registerOutParameter(i + 3, IfxTypes.IFX_TYPE_CURSOR);
                    }
                    else if (databaseType.equals("oracle"))
                        callablestatement.registerOutParameter(i + 3, -10);


            }
            Date beginTime=new Date();
            // long l1 = System.currentTimeMillis();

            callablestatement.execute();
            // long l3 = System.currentTimeMillis();
            Date endTime=new Date();
            ExecuteSqlLogger.log(s+"("+arg_str+")",beginTime,endTime);
            try
            {
                ResultSet resultset;
                if((databaseType.equals("oracle")||databaseType.equals("postgresql"))) {
                    try {
                        resultset = (ResultSet)callablestatement.getObject(i + 3);
                        //增加flag,msg输出参数支持,xiaofeng
                        try{
                            flag=callablestatement.getInt(i+1);
                        }catch(SQLException e){
                            //ignore
                        }
                        try{
                            msg=callablestatement.getString(i+2);
                        }catch(SQLException e){
                            //ignore
                        }
                    }
                    catch(SQLException cursorinvalidate) { resultset = null ; }
                }
                else
                {
                    while((resultset=callablestatement.getResultSet())==null){
                        if(!callablestatement.getMoreResults() && callablestatement.getUpdateCount()==-1)
                            break;
                    }
                }

                if(resultset!=null){
                    parseResultSet(resultset);
                    try{
                        //DeleteSqlCountMonitorUtil.writeLog(getCounts(),s+"("+arg_str+")");
                    }catch (Exception e) {}
                    resultset.close();
                }else{
                    //DeleteSqlCountMonitorUtil.writeLog(-1,s+"("+arg_str+")");
                }
                //增加flag,msg输出参数支持,xiaofeng
                try{
                    flag=callablestatement.getInt(i+1);
                }catch(SQLException e){
                    //ignore
                }
                try{
                    msg=callablestatement.getString(i+2);
                }catch(SQLException e){
                    //ignore
                }
            }
            catch(SQLException sqlexception)
            {
                writeLog(sqlexception) ;
            }

            callablestatement.close();
            bSuccess = true;
        }
        catch(Exception exception)
        {
            setExceptionMsg(exception.getMessage());
            bSuccess = false;
            writeLog(s+" " + arg_str);
            writeLog(exception) ;
        }
        finally
        {
            if(connNode != null){
                connNode.setExec(false);
            }
            try
            {
                if(orgindbtype.equals("st")||orgindbtype.equals("jc")||orgindbtype.equals("gs")||databaseType.equalsIgnoreCase("postgresql")){
                    conn.setAutoCommit(oldautocommit);
                }
                if(FastConnBuffer.isBuffered()){
                    conn.commit();
                }else{
                    givebackConnection(poolname);
                }
            }
            catch(Exception exception2) { }
            lostTime = System.currentTimeMillis()-time;
            if(bSuccess){
                if (poolname == null || poolname.equals(GCONST.getServerName()) || poolname.equals(DataSourceXML.SYS_LOCAL_POOLNAME)) {
                    CacheFactory.getInstance().refreshCacheForProc(s, this, result);
                }else if(isEcologyDb(poolname)){
                    CacheFactory.getInstance().refreshCacheForProc(s, this, result);
                }
            }
        }
        return bSuccess;
    }

    /**
     * 支持标准的存储过程,去掉注册入参 flag msg<br>
     * @param s
     * @param s1
     * @return
     */
    public boolean executeProc2(String s, String s1,String poolname)
    {
        parseArgument(s1);
        if(!"".equals(s) && MonitorSqlUtil.getInstance().isIntercept(s)){
            new BaseBean().writeLog(s+"此sql不符合性能要求，已被拦截！");
            return false;
        }
        this.sqlTmp = s;
        setExceptionMsg("");
//    	 long l = 0L;
//         long l2 = 0L;
        if(s == null || s.trim().equals("")){
            setExceptionMsg("Query statement or procedure name is empty!");
            return false;
        }

        //check if there is the class for this proc  @@@@@@@@@@@@@@@@@@@@@@@@@@
        ProcChecker procChecker = new ProcChecker(new ProcParamStore(s, poolname, this, args, true));
        if (procChecker.hasClass()) {
            try {
                procChecker.executeProc();
                bSuccess = true;
            } catch (Exception e) {
                setExceptionMsg(e.getMessage());
                bSuccess = false;
                writeLog(e);
            }

            return bSuccess;
        }

        /*
         * 取出缓存
         */
        ResultMap result = null;
        if(ConfigMap.get("iscache","").equals("1")){
            if(poolname == null || poolname.equals(GCONST.getServerName()) || poolname.equals(DataSourceXML.SYS_LOCAL_POOLNAME)){
                result = CacheFactory.getInstance().getRecordCacheForProc(s, s1);
                if(result != null && result.getArray() != null){
                    this.init();
                    CacheFactory.getInstance().convertMapToRS(result,this);
                    bSuccess = true ;
                    return true;
                }
            }
        }

        long time = System.currentTimeMillis();
        FastConnNode connNode = null;

        this.poolname = poolname;
        if(FastConnBuffer.isBuffered()){
            connNode = FastConnBuffer.getConnNode(poolname);
            if(connNode == null){
                if(!getConnection(poolname)){
                    setExceptionMsg("Failed to get database connection!");
                    return false;
                }

                connNode = new FastConnNode(conn, System.currentTimeMillis());
                FastConnBuffer.setConnNode(poolname, connNode);
            }else{

                conn = connNode.getConnection();

                if(System.currentTimeMillis() - connNode.getStartTime() > FastConnBuffer.RECONNECT_TIME){
                    //if(System.currentTimeMillis() - connNode.getStartTime() > 200){  // for test
                    try {
                        //System.out.println("~~~~~~~connect buffer recreate a new connection");  // for test
                        givebackConnection(poolname);
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    if(!getConnection(poolname)){
                        setExceptionMsg("Failed to get database connection!");
                        return false;
                    }

                    connNode = new FastConnNode(conn, System.currentTimeMillis());
                    FastConnBuffer.setConnNode(poolname, connNode);
                }
            }
            connNode.setExec(true);

        }else{
            if(!getConnection(poolname)){
                setExceptionMsg("Failed to get database connection!");
                return false;
            }
        }
        databaseType = conn.getDBType() ;

        try {
            parseArgument(s1);
            int i = args.length;
            StringBuilder sb = new StringBuilder();
            sb.append("{call ").append(s).append("(").toString();

            for(int j = 0; j < i ; j++) {
                if(j==0)
                    sb.append("?");
                else
                    sb.append(",?");
            }

            String s2 = sb.append(")}").toString();
            sb.delete(0,sb.length());//make empty

            CallableStatement callablestatement = conn.prepareCall(s2);
            for(int k = 0; k < i; k++)
            {
                callablestatement.setString(k + 1, args[k]);
            }
            Date beginTime=new Date();
            callablestatement.execute();
            Date endTime=new Date();
            ExecuteSqlLogger.log(s+"("+s1+")",beginTime,endTime);
            try
            {
                ResultSet resultset = null;
                while((resultset=callablestatement.getResultSet())==null){
                    if(!callablestatement.getMoreResults() && callablestatement.getUpdateCount()==-1)
                        break;
                }
                if(resultset!=null){
                    parseResultSet(resultset);
                    try{
                        //DeleteSqlCountMonitorUtil.writeLog(getCounts(),s+"("+s1+")");
                    }catch (Exception e) {}
                    resultset.close();
                }else{
                    //DeleteSqlCountMonitorUtil.writeLog(-1,s+"("+s1+")");
                }
            }
            catch(SQLException sqlexception)
            {
                writeLog(sqlexception) ;
            }
            callablestatement.close();
            bSuccess = true;
        }
        catch(Exception exception)
        {
            setExceptionMsg(exception.getMessage());
            bSuccess = false;
            writeLog(s+" " + s1+" "+poolname);
            writeLog(exception) ;
        }
        finally
        {
            if(connNode != null){
                connNode.setExec(false);
            }
            try
            {
                if(FastConnBuffer.isBuffered()){
                    conn.commit();
                }else{
                    givebackConnection(poolname);
                }

            }
            catch(Exception exception2) { }
            lostTime = System.currentTimeMillis()-time;
            if(bSuccess){
                if (poolname == null || poolname.equals(GCONST.getServerName()) || poolname.equals(DataSourceXML.SYS_LOCAL_POOLNAME)) {
                    CacheFactory.getInstance().refreshCacheForProc(s, this, result);
                }else if(isEcologyDb(poolname)){
                    CacheFactory.getInstance().refreshCacheForProc(s, this, result);
                }
            }
        }
        return bSuccess;
    }
    public boolean executeProcNew(String procName,String poolName,List<ProcBean> params){
        if(!"".equals(procName) && MonitorSqlUtil.getInstance().isIntercept(procName)){
            new BaseBean().writeLog(procName+"此sql不符合性能要求，已被拦截！");
            return false;
        }
        this.sqlTmp = procName;
        setExceptionMsg("");
        if(procName == null || procName.isEmpty()){
            setExceptionMsg("Query statement or procedure name is empty!");
            return false;
        }
        /*
         * 取出缓存
         */
        ResultMap result = null;
        if(ConfigMap.get("iscache","").equals("1")){
            if(poolname == null || poolname.equals(GCONST.getServerName()) || poolname.equals(DataSourceXML.SYS_LOCAL_POOLNAME)){
                result = CacheFactory.getInstance().getRecordCacheForProc(procName, poolName,params);
                if(result != null && result.getArray() != null){
                    this.init();
                    CacheFactory.getInstance().convertMapToRS(result,this);
                    bSuccess = true ;
                    return true;
                }
            }
        }

        //check if there is the class for this proc  @@@@@@@@@@@@@@@@@@@@@@@@@@
        ProcChecker procChecker = new ProcChecker(new ProcParamStore(procName, poolname, this, args, true));
        if (procChecker.hasClass()) {
            try {
                procChecker.executeProc();
                bSuccess = true;
            } catch (Exception e) {
                setExceptionMsg(e.getMessage());
                bSuccess = false;
                writeLog(e);
            }

            return bSuccess;
        }


        long time = System.currentTimeMillis();
        FastConnNode connNode = null;

        this.poolname = poolName;
        if(FastConnBuffer.isBuffered()){
            connNode = FastConnBuffer.getConnNode(poolname);
            if(connNode == null){
                if(!getConnection(poolname)){
                    setExceptionMsg("Failed to get database connection!");
                    return false;
                }

                connNode = new FastConnNode(conn, System.currentTimeMillis());
                FastConnBuffer.setConnNode(poolname, connNode);
            }else{

                conn = connNode.getConnection();

                if(System.currentTimeMillis() - connNode.getStartTime() > FastConnBuffer.RECONNECT_TIME){
                    try {
                        givebackConnection(poolname);
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    if(!getConnection(poolname)){
                        setExceptionMsg("Failed to get database connection!");
                        return false;
                    }

                    connNode = new FastConnNode(conn, System.currentTimeMillis());
                    FastConnBuffer.setConnNode(poolname, connNode);
                }
            }
            connNode.setExec(true);

        }else{
            if(!getConnection(poolname)){
                setExceptionMsg("Failed to get database connection!");
                return false;
            }
        }

        databaseType = conn.getDBType() ;

        try {
            StringBuilder sql = new StringBuilder();
            ProcBean procBean;

            sql.append(" call ").append(procName) .append("(");

            boolean isDeleteLast = Boolean.FALSE;

            for (int n = 0; n < params.size(); n++) {
                if (n == 0) {
                    procBean = params.get(n);
                    if ("return".equalsIgnoreCase(procBean.getDataType())) {
                        sql.insert(0," ? = ");
                        isDeleteLast = Boolean.FALSE;
                    } else {
                        sql.append("?,");
                        isDeleteLast = Boolean.TRUE;
                    }
                } else {
                    sql.append("?,");
                    isDeleteLast = Boolean.TRUE;
                }
            }
            if(isDeleteLast) {
                sql.deleteCharAt(sql.length() - 1);
            }
            sql.insert(0, "{ ").append(")}");

            CallableStatement callablestatement = conn.prepareCall(sql.toString());

            LinkedHashMap<Integer,ProcBean> outIndex = new LinkedHashMap<Integer, ProcBean>();

            for(int i=0;i<params.size();i++){
                procBean = params.get(i);

                if("in".equalsIgnoreCase(procBean.getDataType())||"inout".equalsIgnoreCase(procBean.getDataType())){
                    if(procBean.isArray()){
                        callablestatement.setArray(i + 1,getArray(conn.getConnection(),procBean));
                    }else {
                        callablestatement.setString(i + 1, procBean.getValue());
                    }
                }

                if("return".equalsIgnoreCase(procBean.getDataType()) || "out".equalsIgnoreCase(procBean.getDataType()) || "inout".equalsIgnoreCase(procBean.getDataType())){
                    if(procBean.isArray()){
                        callablestatement.registerOutParameter(i + 1 , OracleTypes.ARRAY,procBean.getParamType().toUpperCase());//必须大写
                        outIndex.put(i + 1,procBean);
                    }else {
                        int type = Types.VARCHAR;

                        if ("int".equalsIgnoreCase(procBean.getParamType())) {
                            type = Types.BIGINT;
                        } else if ("long".equalsIgnoreCase(procBean.getParamType())) {
                            type = Types.BIGINT;
                        } else if ("float".equalsIgnoreCase(procBean.getParamType())) {
                            type = Types.FLOAT;
                        } else if ("double".equalsIgnoreCase(procBean.getParamType())) {
                            type = Types.DOUBLE;
                        } else if ("boolean".equalsIgnoreCase(procBean.getParamType())) {
                            type = Types.BOOLEAN;
                        } else if ("date".equalsIgnoreCase(procBean.getParamType())){
                            type = Types.DATE;
                        }
                        callablestatement.registerOutParameter(i + 1, type);
                        outIndex.put(i + 1,procBean);
                    }
                }
            }

            Date beginTime=new Date();

            callablestatement.execute();

            Date endTime=new Date();
            ExecuteSqlLogger.log(procName+"("+params.toString()+")",beginTime,endTime);
            try {

                ResultSet resultset;

                while((resultset=callablestatement.getResultSet())==null){
                    if(!callablestatement.getMoreResults() && callablestatement.getUpdateCount()==-1)
                        break;
                }

                if(resultset!=null){
                    parseResultSet(resultset);
                    try{
                        //DeleteSqlCountMonitorUtil.writeLog(getCounts(),procName+"("+params.toString()+")");
                    }catch (Exception e) {}
                    resultset.close();
                }else{
                    //DeleteSqlCountMonitorUtil.writeLog(-1,procName+"("+params.toString()+")");
                }

                if(outIndex.size()>0){
                    this.output = new HashMap<String, Object>();
                    for (Map.Entry<Integer, ProcBean> entry : outIndex.entrySet()) {
                        ProcBean bean = entry.getValue();
                        if(bean.isArray()){
                            Map<String,Object> map = new HashMap<String, Object>();
                            List<List<ProcBean>> childList = bean.getChildParams();
                            if(childList != null && childList.size()>0){
                                List<ProcBean> procBeanList = childList.get(0);
                                Object[] ary = (Object[]) callablestatement.getArray(entry.getKey()).getArray();
                                for(int i=0;i<procBeanList.size();i++){
                                    ProcBean pb = procBeanList.get(i);
                                    map.put(pb.getName(),ary.length>i?ary[i]:"");
                                }
                                output.put(bean.getName(),map);
                            }
                        }else {
                            output.put(bean.getName(),callablestatement.getObject(entry.getKey()));
                        }
                    }
                }
            }
            catch(SQLException sqlexception)
            {
                writeLog(sqlexception) ;
            }

            callablestatement.close();
            bSuccess = true;
        }catch(Exception exception){
            setExceptionMsg(exception.getMessage());
            bSuccess = false;
            writeLog(poolName +" " + params.toString());
            writeLog(exception) ;
        }finally{
            if(connNode != null){
                connNode.setExec(false);
            }
            try{
                if(FastConnBuffer.isBuffered()){
                    conn.commit();
                }else{
                    givebackConnection(poolname);
                }

            }catch(Exception exception2) { }
            lostTime = System.currentTimeMillis()-time;
            if(bSuccess){
                if (poolname == null || poolname.equals(GCONST.getServerName()) || poolname.equals(DataSourceXML.SYS_LOCAL_POOLNAME)) {
                    CacheFactory.getInstance().refreshCacheForProc(procName, this, result);
                }
            }
        }
        return bSuccess;
    }

    public oracle.sql.ARRAY getArray(Connection conn,ProcBean procBean) throws SQLException {

        StructDescriptor recDesc = StructDescriptor.createDescriptor(procBean.getParamType().toUpperCase(),conn);

        ArrayList<STRUCT> pstruct = new ArrayList<STRUCT>();

        List<List<ProcBean>> list = procBean.getChildParams();

        if(list != null){
            for(int i=0; i<list.size();i++) {
                List<ProcBean> childList = list.get(i);

                Object[] obj = new Object[childList.size()];

                for(int j=0; j<childList.size(); j++){
                    ProcBean childBean = childList.get(j);
                    if(childBean != null){
                        if(childBean.isArray()){
                            obj[j] = getArray(conn,childBean);
                        } else {
                            obj[j] = childBean.getValue();
                        }
                    }
                }

                STRUCT struct = new STRUCT(recDesc, conn, obj);
                pstruct.add(struct);
            }

            oracle.sql.ArrayDescriptor tabDesc = oracle.sql.ArrayDescriptor.createDescriptor(procBean.getValue().toUpperCase(),conn);
            //把list中的元素转换成自定义的类型
            oracle.sql.ARRAY array = new oracle.sql.ARRAY(tabDesc,conn,pstruct.toArray());

            return array;
        }

        return null;

    }

    /**
     * 执行SQL语句，采用默认的链接池
     *
     * @param s    SQL语句
     *
     * @return boolean   如果执行成功，返回true，否则返回false
     */
    @Deprecated
    public boolean executeSql(String s)  {
        return executeSql(s , null) ;
    }

    /**
     * 新的SQL语句执行方式，可以防止SQL注入
     * @param s
     * @param params
     * @return
     */

    public boolean executeQuery(String s, Object... params){
        return executeSql(s,true,null,true,params);
    }

    public boolean executeUpdate(String s, Object... params){
        return executeSql(s,false,null,true,params);
    }

    /**
     * 新的SQL语句执行方式，可以防止SQL注入
     * @param s
     * @param poolname  数据源名称
     * @param params
     * @return
     */
    public boolean executeQueryWithDatasource(String s, String poolname, Object... params){
        return executeSql(s,true,poolname,true,params);
    }

    public boolean executeUpdateWithDatasource(String s, String poolname, Object... params){
        return executeSql(s,false,poolname,true,params);
    }

    public boolean executeSql(String s,boolean isQuerySql, Object... params){
        return executeSql(s,isQuerySql,null,true,params);
    }

    public boolean executeSql(String s,boolean isQuerySql,String poolname, Object... params){
        return executeSql(s,isQuerySql,poolname,true,params);
    }

    private boolean executeSql2(String s,boolean isQuerySql,String poolname, Object... params){
        return executeSql(s,isQuerySql,poolname,true,params);
    }

    @Override
    public boolean executeSql(String s,boolean isQuerySql,String poolname,boolean hasnewconn, Object... params){
        //ConnStatement statement = new ConnStatement();
        if(!"".equals(s) && MonitorSqlUtil.getInstance().isIntercept(s)){
            new BaseBean().writeLog(s+"此sql不符合性能要求，已被拦截！");
            return false;
        }
        this.sqlTmp = s;
        setExceptionMsg("");
        if(s == null || s.trim().equals("")){
            setExceptionMsg("Query statement or procedure name is empty!");
            return false;
        }
        /*
         * 取出缓存
         */
        ResultMap resultMap = null;
        if(ConfigMap.get("iscache","").equals("1")){
            if(poolname == null || poolname.equals(GCONST.getServerName()) || poolname.equals(DataSourceXML.SYS_LOCAL_POOLNAME)){
                resultMap = CacheFactory.getInstance().getRecordCache(s,params);
                if(resultMap != null && resultMap.getArray() != null ){
                    this.init();
                    CacheFactory.getInstance().convertMapToRS(resultMap,this);
                    bSuccess = true ;
                    sqlParserUtil.sqlParser(s, params);
                    return true;
                }
            }
        }

        long time = System.currentTimeMillis();
        FastConnNode connNode =null;


        boolean isEcology = false;
//	 poolname = readDbDeal(s,poolname);
        if (poolname == null || poolname.equals(GCONST.getServerName())
                || poolname.equals(DataSourceXML.SYS_LOCAL_POOLNAME)) {
            isEcology = true;
        }

        this.poolname = poolname;
        //对外部数据源不做任何处理
        boolean flag = false;
        //判断是不是本地数据源，只有本地数据源才做处理
        if(poolname==null||GCONST.getServerName().equals(poolname)||EncodingUtils.containsNativeDB(poolname)||"".equals(poolname)){
            flag = true;
        }
        if(FastConnBuffer.isBuffered() && isEcology){
            connNode = FastConnBuffer.getConnNode(poolname);
            if(connNode == null){
                if(!getConnection(poolname)){
                    setExceptionMsg("Failed to get database connection!");
                    return false;
                }

                connNode = new FastConnNode(conn, System.currentTimeMillis());
                FastConnBuffer.setConnNode(poolname, connNode);
            }else{

                conn = connNode.getConnection();
                try {
                    if(conn.isClosed()){
                        getConnection(poolname);
                        connNode = new FastConnNode(conn, System.currentTimeMillis());
                        FastConnBuffer.setConnNode(poolname, connNode);
                    }
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
                if(System.currentTimeMillis() - connNode.getStartTime() > FastConnBuffer.RECONNECT_TIME){
                    //if(System.currentTimeMillis() - connNode.getStartTime() > 200){  // for test
                    try {
                        //System.out.println("~~~~~~~connect buffer recreate a new connection");  // for test
                        givebackConnection(poolname,s);
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    if(!getConnection(poolname)){
                        setExceptionMsg("Failed to get database connection!");
                        return false;
                    }
                    connNode = new FastConnNode(conn, System.currentTimeMillis());
                    FastConnBuffer.setConnNode(poolname, connNode);
                }
            }
            connNode.setExec(true);
        }else{
            if(!getConnection(poolname)){
                setExceptionMsg("Failed to get database connection!");
                return false;
            }
        }

        //设置oracle忽略大小写(符合指定条件生效)
        OracleConvertSort oracleConvertSort =  new OracleConvertSort();
        oracleConvertSort.setIgnoreCase(conn, s);

        PreparedStatement ps = null;
        if(flag &&EncodingUtils.encodingStrategy==EncodingUtils.UNICODEENCODING_STRATEGY){
            s = EncodingUtils.toUNICODE(s);
        }

        //transform sqls containing "insert into" in dbs without the sequence tables
        boolean multiExecute = false;
        IdHandler idHandler = null;
        if (!isQuerySql && !Arrays.asList(RecordSetExecutionInterface.LEGACY_DB_TYPES).contains(getOrgindbtype())) {
      //  if (!isQuerySql && Stream.of(RecordSetExecutionInterface.LEGACY_DB_TYPES).noneMatch(v->v.equalsIgnoreCase(getOrgindbtype()))) {
            idHandler = new IdHandler(s);
            if (idHandler.isTransformed()) {
                if (idHandler.isInsertSelectSql()) {
                    multiExecute = true;
                    s = idHandler.getSelectSqlPart();
                    isQuerySql = true;
                }else {
                    s = idHandler.getTransFormedSql();
                }
            }
        }
        ResultSet resultset = null;
        try{

            if(params == null||params.length ==0){
                try{
                    if(flag&&EncodingUtils.encodingStrategy == EncodingUtils.SQLPARSER_STRATEGY){
                        Class c=Class.forName("weaver.conn.sqlparser.FormatSQL");
                        Method m = c.getDeclaredMethod("parse",String.class);
                        Object[] result = (Object[]) m.invoke(c.newInstance(), s);
                        String newsql = result[0].toString();
                        Vector paramss = (Vector)result[1];
                        Object[] paramsss = new Object[] { paramss };
                        //下次将不再满足params == null 不会出现死循环
                        if( paramsss.length>0){
                            if(executeSql2(newsql,isQuerySql,poolname,hasnewconn,paramss))
                                return true;
                        }
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
            }

            int i=1;

            //先进行敏感词过滤处理

            Object[] objArrForSensitive = sqlParserUtilForSensitvie.sqlParser(s, params);
            s = objArrForSensitive[0].toString();
            params = ((List) objArrForSensitive[1]).toArray();

            //敏感词过滤完成后再进行数据加密处理
            Object[] objArr = sqlParserUtil.sqlParser(s, params);
            s = objArr[0].toString();
            params = ((List)objArr[1]).toArray();
            ps = conn.prepareStatement(s);
            String dbtype=conn.getDBType();
            for(Object param : params){
                if ((param instanceof Vector)) {
                    Vector pars = (Vector)param;
                    for (int j = 0; j < pars.size(); j++) {
                        Object para = pars.get(j);
                        if(dbtype.equalsIgnoreCase("postgresql"))
                        {
                            if("null".equals((""+param).trim().toLowerCase())||(""+param).trim().equalsIgnoreCase(""))
                                ps.setObject(i,null);
                            else
                                ps.setObject(i,param);
                            i++;
                            continue;
                        }
                        if (((para instanceof Integer)) || ((para instanceof Long))){
                            //需要转码时，将参数先转换为unicode lrf
                            if(flag){
                                if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                                    para = EncodingUtils.toUNICODE(para);
                                }
                            }
                            ps.setInt(i, Util.getIntValue(""+para));
                        }
                        else if (para == null)
                            ps.setNull(i, 0);
                        else if ((para instanceof Float))
                            ps.setFloat(i, Util.getFloatValue(""+para));
                        else if (((para instanceof BigDecimal)) || ((para instanceof Double)))
                            //ps.setBigDecimal(i, (para instanceof BigDecimal) ? (BigDecimal)para : new BigDecimal(Util.getDoubleValue(""+para)));
                            ps.setObject(i,para);
                        else if ((para instanceof java.sql.Date))
                            ps.setDate(i, (java.sql.Date)para);
                        else if (((para instanceof String)) || ((para instanceof Character))){
                            if(dbtype.equalsIgnoreCase("postgresql")&&(""+para).trim().equalsIgnoreCase(""))
                                ps.setObject(i,null);
                            else if("null".equals((""+para).trim().toLowerCase())){
                                //ps.setNull(i,Types.NULL);
                                ps.setObject(i,null);
                            }else{
                                if(flag){
                                    if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                                        para = EncodingUtils.toUNICODE(para);
                                    }
                                }
                                ps.setString(i, ""+para);
                            }
                        }else if ((para instanceof Clob)){
                            String str = "";
                            if(flag){
                                if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                                    str = EncodingUtils.toUNICODE(para);
                                    para = EncodingUtils.StringToClob(str, conn);
                                }
                            }
                            ps.setClob(i, (Clob)para);
                        }
                        else if ((para instanceof Blob))
                            ps.setBlob(i, (Blob)para);
                        else {
                            if(flag){
                                if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                                    para=EncodingUtils.toUNICODE(para);
                                }
                            }
                            ps.setObject(i, para);
                        }
                        i++;
                    }
                }else if ((param instanceof List)) {
                    List pars = (List)param;
                    for (int j = 0; j < pars.size(); j++) {
                        Object para = pars.get(j);
                        if(dbtype.equalsIgnoreCase("postgresql"))
                        {
                            if("null".equals((""+param).trim().toLowerCase())||(""+param).trim().equalsIgnoreCase(""))
                                ps.setObject(i,null);
                            else
                                ps.setObject(i,param);
                            i++;
                            continue;
                        }
                        if (((para instanceof Integer)) || ((para instanceof Long))){
                            //需要转码时，将参数先转换为unicode lrf
                            if(flag){
                                if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                                    para = EncodingUtils.toUNICODE(para);
                                }
                            }
                            ps.setInt(i, Util.getIntValue(""+para));
                        }
                        else if (para == null)
                            //ps.setNull(i, Types.NULL);
                            ps.setObject(i,null);
                        else if ((para instanceof Float))
                            ps.setFloat(i, Util.getFloatValue(""+para));
                        else if (((para instanceof BigDecimal)) || ((para instanceof Double)))
                            //ps.setBigDecimal(i, (para instanceof BigDecimal) ? (BigDecimal)para : new BigDecimal(Util.getDoubleValue(""+para)));
                            ps.setObject(i,para);
                        else if ((para instanceof java.sql.Date))
                            ps.setDate(i, (java.sql.Date)para);
                        else if (((para instanceof String)) || ((para instanceof Character))){
                            if(dbtype.equalsIgnoreCase("postgresql")&&(""+para).trim().equalsIgnoreCase(""))
                                ps.setObject(i,null);
                            else if("null".equals((""+para).trim().toLowerCase())){
                                //ps.setNull(i,Types.NULL);
                                ps.setObject(i,null);
                            }else{
                                if(flag){
                                    if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                                        para = EncodingUtils.toUNICODE(para);
                                    }
                                }
                                ps.setString(i, ""+para);
                            }
                        }else if ((para instanceof Clob)){
                            String str = "";
                            if(flag){
                                if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                                    str = EncodingUtils.toUNICODE(para);
                                    para = EncodingUtils.StringToClob(str, conn);
                                }
                            }
                            ps.setClob(i, (Clob)para);
                        }
                        else if ((para instanceof Blob))
                            ps.setBlob(i, (Blob)para);
                        else {
                            if(flag){
                                if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                                    para=EncodingUtils.toUNICODE(para);
                                }
                            }
                            ps.setObject(i, para);
                        }
                        i++;
                    }
                } else {
                    if(dbtype.equalsIgnoreCase("postgresql"))
                    {
                        if("null".equals((""+param).trim().toLowerCase())||(""+param).trim().equalsIgnoreCase(""))
                            ps.setObject(i,null);
                        else
                           ps.setObject(i,param);
                        i++;
                        continue;
                    }
                    if ((param instanceof Integer)){
                        if(flag){
                            if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                                param = EncodingUtils.toUNICODE(param);
                            }
                        }
                        ps.setInt(i, Util.getIntValue(""+param));
                    }
                    else if ((param instanceof Long)){
                        if(flag){
                            if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                                param = EncodingUtils.toUNICODE(param);
                            }
                        }
                        long value = Long.valueOf(param+"");
                        ps.setLong(i, value);
                    }
                    else if (param == null)
                        //ps.setNull(i, Types.NULL);
                        ps.setObject(i,null);
                    else if ((param instanceof Float))
                        ps.setFloat(i, Util.getFloatValue(""+param));
                    else if (((param instanceof BigDecimal)) || ((param instanceof Double)))
                        //ps.setBigDecimal(i, (param instanceof BigDecimal) ? (BigDecimal)param : new BigDecimal(Util.getDoubleValue(""+param)));
                        ps.setObject(i,param);
                    else if ((param instanceof java.sql.Date))
                        ps.setDate(i, (java.sql.Date)param);
                    else if (((param instanceof String)) || ((param instanceof Character))){
                        if(dbtype.equalsIgnoreCase("postgresql")&&(""+param).trim().equalsIgnoreCase(""))
                            ps.setObject(i,null);
                        else if("null".equals((""+param).trim().toLowerCase())){
                            //ps.setNull(i,Types.NULL);
                            ps.setObject(i,null);
                        }else{
                            if(flag){
                                if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                                    param = EncodingUtils.toUNICODE(param);
                                }
                            }
                            ps.setString(i, ""+param);
                        }
                    }else if ((param instanceof Clob)){
                        //oracle clob类型的存储，先将clob转换成String，然后将String转换为unicode编码 ，以String方式入库
                        String str = "";
                        if(flag){
                            if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                                str = EncodingUtils.toUNICODE(param);
                                param = EncodingUtils.StringToClob(str, conn);
                            }
                        }
                        ps.setClob(i, (Clob)param);
                    }
                    else if ((param instanceof Blob))
                        ps.setBlob(i, (Blob)param);
                    else {
                        if(flag){
                            if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                                param=EncodingUtils.toUNICODE(param);
                            }
                        }
                        ps.setObject(i, param);
                    }
                    i++;
                }
            }
            Date beginTime=new Date();
            if(isQuerySql){
                ps.executeQuery();
                Date endTime=new Date();
                ExecuteSqlLogger.log(s+","+formatParams(params),beginTime,endTime);
                resultset = ps.getResultSet();
                if(resultset != null) {
                    parseResultSet(resultset);
                    resultset.close();
                }

            }else{
                int counts = ps.executeUpdate();
                setUpdateCount(counts);
                Date endTime=new Date();
                ExecuteSqlLogger.log(s+","+formatParams(params),beginTime,endTime);
                try{
                    //DeleteSqlCountMonitorUtil.writeLog(counts,s+","+formatParams(params));
                }catch (Exception e) {}
            }
            bSuccess = true;

            //execute insert sql part
            if (multiExecute && idHandler!=null) {
                String insertSql = idHandler.getTransFormedSql();
                List<List<Object>> out_list = new ArrayList<>();
                for (Object o : getArray()) {
                    out_list.add(new ArrayList<>(Arrays.asList((Object[])o)));
                }
                out_list = idHandler.supplementBatchParams(out_list);
                return executeBatchSql(insertSql, out_list, poolname);
            }
       //     EncyParam.getInstance().databaseok=true;
            return true;
        }catch(Exception e){
//            if(e.getMessage().indexOf("超过了服务端可定义的游标数目限制65536")>-1||e.getMessage().indexOf("连接被断开")>-1)
//                EncyParam.getInstance().databaseok=false;
            if(resultset != null) {
                try{
                    resultset.close();
                }catch(Exception ee){}
            }
            setExceptionMsg(e.getMessage());
            String sql = s;
            for(Object param : params){
                sql += ","+param;
            }
            writeLog(sql);
            writeLog(e);
            e.printStackTrace();
            bSuccess = false;
            return false;
        } finally
        {
            if(conn!=null){
                oracleConvertSort.reset(conn);
            }
            if(connNode != null ){
                connNode.setExec(false);
            }
            try{
                ps.close();
            }catch(Exception e){}
            try
            {
                if(FastConnBuffer.isBuffered() && isEcology){
                    if(!MonitorSqlUtil.isOnlySelect(s)) {
                        conn.commit();
                    }
                }else{
                    givebackConnection(poolname,s);
                }
            }
            catch(Exception exception2) { exception2.printStackTrace();}
            lostTime = System.currentTimeMillis()-time;
            if(bSuccess){
                if (poolname == null || poolname.equals(GCONST.getServerName()) || poolname.equals(DataSourceXML.SYS_LOCAL_POOLNAME)) {
                    CacheFactory.getInstance().refreshCache(s, this, resultMap);
                }else if(isEcologyDb(poolname)){
                    CacheFactory.getInstance().refreshCache(s, this, resultMap);
                }
            }
        }
    }

    private String formatParams(Object... params){
        List paramsList = new ArrayList();
        for(Object param : params){
            if ((param instanceof List)) {
                for(Object pi : (List)param){
                    paramsList.add(pi);
                }
            }else if ((param instanceof Vector)){
                for(Object pi : (Vector)param){
                    paramsList.add(pi);
                }
            }
            else{
                paramsList.add(param);
            }
        }
        return paramsList.toString();
    }


    /**
     * 批量执行SQL语句，带事务处理
     * @param sql
     * @param params
     * @throws Exception
     */

    public boolean executeBatchSql(String sql, List<List> params) {
        return executeBatchSql(sql, new ArrayList(params), null);
    }

    @Override
    public int[] executeBatchSql_proxy(String sql, List<List<Object>> params, String poolName) {
        executeBatchSql(sql, params, poolName);
        return getBatchCounts();
    }

    public boolean executeBatchSql(String sql, List<List<Object>> params, String poolname) {
        setExceptionMsg("");
        long startTime = new Date().getTime();
        //writeLog("======sql is "+sql+"=============start time is "+new Date()+"======params.size() is " + params.size());
        if (params == null || params.size() == 0) {
            setExceptionMsg("Parameters is empty.");
            return false;
        }
        // if (conn == null || conn.isClosed()) {
        if (!getConnection(poolname)){
            setExceptionMsg("Failed to get database connection!");
            return false;
        }
        // }
        // 得到数据库类型
        databaseType = conn.getDBType();
        boolean flag = false;
        if (poolname == null || GCONST.getServerName().equals(poolname) || EncodingUtils.containsNativeDB(poolname) || "".equals(poolname)) {
            // 对于这种存储过程或预处理方式，若当前为sqlparser模式（默认sqlserevr数据库编码为nvarchar），则不需要实际执行sqlparser，因为存储过程或者预处理方式存储数据没有问题
            if (EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY) {
                flag = true;
                sql = EncodingUtils.toUNICODE(sql);
            }
        }

//        transform sqls containing "insert into" in dbs without the sequence tables
        if (!Arrays.asList(RecordSetExecutionInterface.LEGACY_DB_TYPES).contains(getOrgindbtype())) {
       // if (Stream.of(RecordSetExecutionInterface.LEGACY_DB_TYPES).noneMatch(v->v.equalsIgnoreCase(getOrgindbtype()))) {
            IdHandler idHandler = new IdHandler(sql, true);
            if (idHandler.isTransformed()) {
                sql = idHandler.getTransFormedSql();
                try {
                    params = idHandler.supplementBatchParams(params);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new UnsupportedOperationException();
                }
            }
        }

        PreparedStatement pstmt = null;
        List<Object> paramList = null;
        try {
            conn.setAutoCommit(false);
            pstmt = conn.prepareStatement(sql);
            boolean hasMoreBatch = false;
            int k = 0;
            List<String> sqlLog = new ArrayList<String>();
            //解析sql，得到表名和所有的参数名
            Object[] tableFieldList = sqlParserUtil.getTableNameAndFileName(sql);
            String tableName = null;
            List<String> paramNames = null;
            boolean encryptFlag = false;
            boolean filterSentiveFlag = false;
            int paramNamesSize = 0;
            if(tableFieldList!=null){
                encryptFlag = true;
                filterSentiveFlag = true;
                tableName = (String)tableFieldList[0];
                paramNames = (List<String>)tableFieldList[1];
                paramNamesSize = paramNames.size();
            }else{
                tableFieldList = sqlParserUtilForSensitvie.getTableNameAndFileName(sql);
                if(tableFieldList!=null){
                    filterSentiveFlag = true;
                    tableName = (String)tableFieldList[0];
                    paramNames = (List<String>)tableFieldList[1];
                    paramNamesSize = paramNames.size();
                }
            }
            EncryptUtil eu = new EncryptUtil();
            for (int i = 0; i < params.size(); i++) {
                k++;
                paramList = params.get(i);
                sqlLog.add(sql+","+formatParams(paramList));
                // 参数填充
                for (int j = 0; j < paramList.size(); j++) {
                    Object param = paramList.get(j);
                    if(filterSentiveFlag){
                        if(j<paramNamesSize) {
                            param = CheckSensitiveWordBiz.checkSensitive(tableName,paramNames.get(j),param);
                        }
                    }
                    if(encryptFlag) {
                        if(j<paramNamesSize) {
                            param = eu.encryt(tableName, paramNames.get(j), param, null);
                        }
                    }
                    int parameterIndex = j + 1;
                    if (param instanceof Integer) {
                        pstmt.setInt(parameterIndex, (Integer) param);
                    } else if (param instanceof String) {
                        if (flag) {
                            pstmt.setString(parameterIndex, EncodingUtils.toUNICODE((String) param));
                        } else {
                            pstmt.setString(parameterIndex, (String) param);
                        }
                    } else if (param instanceof Double) {
                        pstmt.setDouble(parameterIndex, (Double) param);
                    } else if (param instanceof Float) {
                        pstmt.setFloat(parameterIndex, (Float) param);
                    } else if (param instanceof Long) {
                        pstmt.setLong(parameterIndex, (Long) param);
                    } else if (param instanceof byte[]){
                        pstmt.setBytes(parameterIndex , (byte[]) param);
                    } else if (param instanceof BigDecimal){
                        pstmt.setObject(parameterIndex,param);
                    } else if (param instanceof java.sql.Date){
                        pstmt.setDate(parameterIndex,(java.sql.Date)param);
                    } else {
                        if (flag) {
                            pstmt.setString(parameterIndex, EncodingUtils.toUNICODE((String) param));
                        } else {
                            pstmt.setString(parameterIndex, (String) param);
                        }
                    }

                }
                hasMoreBatch = true;
                pstmt.addBatch();
                if(k>=5000){
                    Date beginTime=new Date();
                    int[] counts = pstmt.executeBatch();
                    conn.commit();
                    Date endTime=new Date();
                    for(int n=0;n<sqlLog.size();n++){
                        ExecuteSqlLogger.log(sqlLog.get(n),beginTime,endTime);
                        try{
                            //DeleteSqlCountMonitorUtil.writeLog(counts[n],sqlLog.get(n));
                        }catch (Exception e) {}
                    }
                    pstmt.clearBatch();
                    sqlLog.clear();
                    hasMoreBatch = false;
                    // writeLog("====i is "+i+"====k is "+k+"=====sql is "+sql+"=============commit time is "+new Date());
                    k = 0;
                }
            }
            if(hasMoreBatch){
                Date beginTime=new Date();
                int[] counts = pstmt.executeBatch();
                setBatchCounts(counts);
                conn.commit();
                Date endTime=new Date();
                for(int n=0;n<sqlLog.size();n++){
                    ExecuteSqlLogger.log(sqlLog.get(n),beginTime,endTime);
                    try{
                        //DeleteSqlCountMonitorUtil.writeLog(counts[n],sqlLog.get(n));
                    }catch (Exception e) {}
                }
                // writeLog("======sql is "+sql+"===hasMoreBatch="+hasMoreBatch+"=========commit time is "+new Date());
            }
            return true;
        } catch (SQLException e) {
            setExceptionMsg(e.getMessage());
            writeLog(">>>>执行过程出错");
            writeLog(sql);
            // writeLog(params.toString());
            writeLog(e);
            //e.printStackTrace();
            //throw e;
            return false;
        } finally {
            //清除缓存
            if (poolname == null || poolname.equals(GCONST.getServerName())) {
                CacheFactory.getInstance().removeCacheForSql(sql);
            }

            try {
                if (pstmt != null) {
                    pstmt.close();
                    // writeLog(">>>>stmt正常关闭");
                }
            } catch (SQLException e) {
                writeLog(">>>>关闭stmt出错");
                writeLog(e);
            }
            try {
                //自动提交时才归还链接
//	             if (conn.getAutoCommit()) {
//	                 givebackConnection(poolname);
//	                 conn = null;
//	             }
                givebackConnection(poolname);
                conn = null;
            } catch (SQLException e) {
                writeLog(">>>>关闭conn出错");
                writeLog(e);
            }
            // writeLog("======sql is "+sql+"=============end time is "+new Date()+"========execute time is "+(new Date().getTime()-startTime)+"ms");
        }
    }



    /**
     * 执行SQL语句，采用指定的链接池
     *
     * @param s    SQL语句
     * @param poolname    指定的链接池名称，如果为null 则使用默认的链接池
     *
     * @return boolean   如果执行成功，返回true，否则返回false
     */
    @Deprecated
    public boolean executeSql(String s ,String poolname)
    {
        if(!"".equals(s) && MonitorSqlUtil.getInstance().isIntercept(s)){
            new BaseBean().writeLog(s+"此sql不符合性能要求，已被拦截！");
            return false;
        }
        this.sqlTmp = s;
        setExceptionMsg("");
        if(s == null || s.trim().equals("")){
            setExceptionMsg("Query statement or procedure name is empty!");
            return false;
        }

        /*
         * 取出缓存
         */
        ResultMap resultMap = null;
        if(ConfigMap.get("iscache","").equals("1")){
            if(poolname == null || poolname.equals(GCONST.getServerName()) || poolname.equals(DataSourceXML.SYS_LOCAL_POOLNAME)){
                resultMap = CacheFactory.getInstance().getRecordCache(s);
                if(resultMap != null && resultMap.getArray() != null){
                    this.init();
                    CacheFactory.getInstance().convertMapToRS(resultMap,this);
                    bSuccess = true ;
                    sqlParserUtil.sqlParser(s);
//            		 LOGGER.info("缓存结果查询："+s+"总花费时间："+(System.currentTimeMillis()-time));
                    return true;
                }
            }
        }
        long time = System.currentTimeMillis();
        FastConnNode connNode = null;
        boolean isEcology = false;
//    	 poolname = readDbDeal(s,poolname);
        if (poolname == null || poolname.equals(GCONST.getServerName())
                || poolname.equals(DataSourceXML.SYS_LOCAL_POOLNAME)) {
            isEcology = true;
        }


        this.poolname = poolname;
        boolean flag = false;
        //首先判断是否本地数据源，只有本地数据源才做编码转换或者sql解析处理
        if(poolname==null||GCONST.getServerName().equals(poolname)||EncodingUtils.containsNativeDB(poolname)||"".equals(poolname)){
            flag = true;
        }
        if(flag){
            if(EncodingUtils.encodingStrategy == EncodingUtils.SQLPARSER_STRATEGY){
                try{
                    Class c=Class.forName("weaver.conn.sqlparser.FormatSQL");
                    Method m = c.getDeclaredMethod("parse",String.class);
                    Object[] result = (Object[]) m.invoke(c.newInstance(), s);
                    String newsql = result[0].toString();
                    Vector params = (Vector)result[1];

                    if (s.trim().toLowerCase().startsWith("select")) {
                        if(executeQuery(newsql, new Object[] { params }))
                            return true;
                    }else if(executeUpdate(newsql, new Object[] { params })){
                        return true;
                    }
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
//    			 return false;
            }else if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                s = EncodingUtils.toUNICODE(s);
            }
        }
        if(FastConnBuffer.isBuffered() && isEcology){
            connNode = FastConnBuffer.getConnNode(poolname);
            if(connNode == null){
                if(!getConnection(poolname)){
                    setExceptionMsg("Failed to get database connection!");
                    return false;
                }

                connNode = new FastConnNode(conn, System.currentTimeMillis());
                FastConnBuffer.setConnNode(poolname, connNode);
            }else{

                conn = connNode.getConnection();
                try {
                    if(conn.isClosed()){
                        getConnection(poolname);
                        connNode = new FastConnNode(conn, System.currentTimeMillis());
                        FastConnBuffer.setConnNode(poolname, connNode);
                    }
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
                if(System.currentTimeMillis() - connNode.getStartTime() > FastConnBuffer.RECONNECT_TIME){
                    //if(System.currentTimeMillis() - connNode.getStartTime() > 200){  // for test
                    try {
                        //System.out.println("~~~~~~~connect buffer recreate a new connection");  // for test
                        givebackConnection(poolname,s);
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    if(!getConnection(poolname)){
                        setExceptionMsg("Failed to get database connection!");
                        return false;
                    }

                    connNode = new FastConnNode(conn, System.currentTimeMillis());
                    FastConnBuffer.setConnNode(poolname, connNode);
                }
            }
            connNode.setExec(true);
        }else{
            if(!getConnection(poolname)){
                setExceptionMsg("Failed to get database connection!");
                return false;
            }
        }
        //设置oracle忽略大小写(符合指定条件生效)
        OracleConvertSort oracleConvertSort =  new OracleConvertSort();
        oracleConvertSort.setIgnoreCase(conn, s);

        databaseType = conn.getDBType() ;
        ResultSet resultset = null;
        Statement statement = null;
        try
        {   //check sql
            String sql = s;
            String sql1=s;
            if(checksql){
                try{
                    sql = Util.replace(sql, "'[^']*'", "", 0);
                }catch(Exception e){
                    writeLog("regex parse error:"+sql);
                }
                if (sql.indexOf(";") > -1||sql.indexOf("--")>-1) {
                    writeLog("illegal sql statement:" + s);
                    setExceptionMsg("illegal sql statement:" + s);
                    return false;
                }
            }

            //transform sqls containing "insert into" in dbs without the sequence tables
            boolean multiExecute = false;
            IdHandler idHandler = null;
            if (!Arrays.asList(RecordSetExecutionInterface.LEGACY_DB_TYPES).contains(getOrgindbtype())) {
         //   if (Stream.of(RecordSetExecutionInterface.LEGACY_DB_TYPES).noneMatch(v->v.equalsIgnoreCase(getOrgindbtype()))) {
                idHandler = new IdHandler(s);
                if (idHandler.isTransformed()) {
                    if (idHandler.isInsertSelectSql()) {
                        multiExecute = true;
                        s = idHandler.getSelectSqlPart();
                    }else {
                        s = idHandler.getTransFormedSql();
                    }
                }
            }


            //check end
            statement= conn.createStatement();
            s = sqlParserUtilForSensitvie.sqlParser(s);
            s = sqlParserUtil.sqlParser(s);
            Date beginTime=new Date();
            statement.execute(s);
            resultset= statement.getResultSet();

            Date endTime=new Date();
            ExecuteSqlLogger.log(s,beginTime,endTime);

            if(resultset != null) {                        // bug mod by liuyu
                parseResultSet(resultset);
                resultset.close();
            }else{
                try{
                    int updateCount = statement.getUpdateCount();
                    //DeleteSqlCountMonitorUtil.writeLog(updateCount,s);
                }catch (Exception e) {}
            }


            //execute insert sql part
            if (multiExecute && idHandler!=null) {
                String insertSql = idHandler.getTransFormedSql();
                List<List<Object>> out_list = new ArrayList<>();
                for (Object o : getArray()) {
                    out_list.add(new ArrayList<>(Arrays.asList((Object[])o)));
                }
                out_list = idHandler.supplementBatchParams(out_list);
                return executeBatchSql(insertSql, out_list, poolname);
            }
          //  EncyParam.getInstance().databaseok=true;
            bSuccess = true;
            // msg="执行成功";
            // flag=0;
        }
        catch(Exception exception)
        {
//            if(exception.getMessage().indexOf("超过了服务端可定义的游标数目限制65536")>-1||exception.getMessage().indexOf("连接被断开")>-1)
//                EncyParam.getInstance().databaseok=false;
            setExceptionMsg(exception.getMessage());
            bSuccess = false;
            // msg=exception.getMessage();
            if(resultset != null) {
                try{// bug mod by liuyu
                    resultset.close();
                }catch(Exception e){}
            }
            // flag=-1;
            writeLog(s);
            writeLog(exception) ;
        }
        finally
        {
            //还原属性设置
            if(conn!=null){
                oracleConvertSort.reset(conn);
            }
            if(connNode != null){
                connNode.setExec(false);
            }
            try
            {
                statement.close();
                if(FastConnBuffer.isBuffered() && isEcology){
                    if(!MonitorSqlUtil.isOnlySelect(s)) {
                        conn.commit();
                    }
                }else{
                    givebackConnection(poolname,s);
                }
            }
            catch(Exception exception2) {exception2.printStackTrace(); }

            if(bSuccess){
                if (poolname == null || poolname.equals(GCONST.getServerName()) || poolname.equals(DataSourceXML.SYS_LOCAL_POOLNAME)) {
                    lostTime = System.currentTimeMillis()-time;
                    CacheFactory.getInstance().refreshCache(s, this, resultMap);
                }else if(isEcologyDb(poolname)){
                    lostTime = System.currentTimeMillis()-time;
                    CacheFactory.getInstance().refreshCache(s, this, resultMap);
                }
            }
        }
        return bSuccess;
    }

    private boolean isEcologyDb(String poolname) {
        String url = getPropValue(GCONST.getConfigFile(), "ecology.url");
        String host = ExternalDataSourceManager.getExternalDS(poolname).getHost();
        if(url != null && host !=null){
            if(url.indexOf(host) >-1){
                return true;
            }
        }
        return false;
    }

    /**
     * 根据数据源执行sql
     * @param sql
     * @param datasourceName  数据源名称，此名称为在数据源配置页面配置的名称
     * @return
     */
    public boolean executeSqlWithDataSource(String sql ,String datasourceName){
        if(!"".equals(sql) && MonitorSqlUtil.getInstance().isIntercept(sql)){
            new BaseBean().writeLog(sql+"此sql不符合性能要求，已被拦截！");
            return false;
        }
        this.sqlTmp = sql;
        setExceptionMsg("");
        BaseDataSource baseDataSource = ExternalDataSourceManager.getExternalDS(datasourceName);
        if(baseDataSource!=null){
            Connection connection = null;
            PreparedStatement psm = null;
            ResultSet rs1 = null;
            boolean hasSqlParse = false;
            //weaver_enableMultiLangEncoding。properties配置文件中必须加入本地数据源 在数据源配置的名称
            //如果是本地数据源，作如下处理,已经是预处理方式，不需要再考虑sqlserevr模式下的的sqlparser，目前尚不确定在预处理语句中包含 韩文会有什么问题
            if(EncodingUtils.containsNativeDB(datasourceName)){
                if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                    sql = EncodingUtils.toUNICODE(sql);
                }else if(EncodingUtils.encodingStrategy == EncodingUtils.SQLPARSER_STRATEGY){
                    try{
                        Class c=Class.forName("weaver.conn.sqlparser.FormatSQL");
                        Method m = c.getDeclaredMethod("parse",String.class);
                        Object[] result = (Object[]) m.invoke(c.newInstance(), sql);
                        String newsql = result[0].toString();
                        Vector params = (Vector)result[1];
                        connection = baseDataSource.getConnection();
                        psm= connection.prepareStatement(newsql);
                        int j = 1;
                        for(Object param : params){
                            if(param instanceof Integer ){
                                psm.setInt(j,Util.getIntValue(""+param));
                            }else if ((param instanceof Long)){
                                long value = Long.valueOf(param+"");
                                psm.setLong(j, value);
                            }else if(param instanceof Float){
                                psm.setFloat(j,Util.getFloatValue(""+param));
                            }else if(param instanceof BigDecimal || param instanceof Double){
                                //psm.setBigDecimal(j,(param instanceof BigDecimal)?(BigDecimal)param:new BigDecimal(""+param));
                                psm.setObject(j,param);
                            }else if(param instanceof java.sql.Date){
                                psm.setDate(j,(java.sql.Date)param);
                            }else if(param instanceof String || param instanceof Character){
                                psm.setString(j,""+param);
                            }else if(param == null){
                                //statement.setNull(i);
                                psm.setObject(j, param);
                            }else if(param instanceof Clob){
                                psm.setClob(j,(Clob)param);
                            }else if(param instanceof Blob){
                                psm.setBlob(j,(Blob)param);
                            }else{
                                psm.setObject(j,param);
                            }
                            j++;
                        }
                    }catch(Exception e){
                        writeLog("Serious Error!!! Sqlparser Error!!");
                        try {
                            psm.close();
                            connection.close();
                        } catch (SQLException e1) {
                            e1.printStackTrace();
                        }
                    }finally{
                        hasSqlParse = true;
                    }
                }
            }
            try {
                //如果未经过SQlParser解析，初始化ps对象
                if(!hasSqlParse){
                    connection = baseDataSource.getConnection();
                    psm= connection.prepareStatement(sql);
                }
                Date beginTime=new Date();
                psm.execute();
                rs1 = psm.getResultSet();
                if(rs1 != null) {                        // bug mod by liuyu
                    parseResultSet(rs1);
                }
                Date endTime=new Date();
                ExecuteSqlLogger.log(sql,beginTime,endTime);
                try{
                    //DeleteSqlCountMonitorUtil.writeLog(getCounts(),sql);
                }catch (Exception e) {}
                bSuccess = true;
            }catch(Exception e){
                setExceptionMsg(e.getMessage());
                bSuccess = false;

                writeLog(sql);
                writeLog(e) ;
            }finally{
                try {
                    if(rs1!=null){
                        rs1.close();
                    }
                    if(psm!=null){
                        psm.close();
                    }
                    if(connection!=null){
                        connection.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return bSuccess;
    }


    /**
     * 执行存储过程，采用默认的链接池
     *
     * @param s    存储过程名称
     * @param s1   存储过程参数，多个参数中间用Util.getSeparator()分开
     *
     * @return boolean   如果执行成功，返回true，否则返回false
     */
    public boolean execute(String s, String s1)
    {
        return executeProc(s, s1);
    }

    /**
     * 执行SQL语句，采用默认的链接池
     *
     * @param s    SQL语句
     *
     * @return boolean   如果执行成功，返回true，否则返回false
     */
    public boolean execute(String s)
    {
        return executeSql(s);
    }


    /**
     * 获得查询记录的总数
     *
     * @return int   查询记录的总数
     */
    public int getCounts()
    {
        return array.size();
    }

    /**
     * 获得查询的字段数
     *
     * @return int   查询记录的字段数
     */
    public int getColCounts()
    {
        return array.isEmpty() ? 0 : ((Object[])array.get(0)).length;
    }


    /**
     * 获得查询的字段名数组，数组依照查询顺序排列字段名
     *
     * @return String []   查询的字段名数组
     */
    public String [] getColumnName()
    {
        return columnName;
    }

    public int [] getColumnType()
    {
        return columnType;
    }

    /**
     * 获得查询的指定位置的数据库字段的字段名称
     *
     * @param columnIndex    数据库字段在查询语句中的位置
     *
     * @return String    指定位置的数据库字段的字段名称
     */
    public String  getColumnName(int columnIndex)
    {
        return columnName[columnIndex-1];
    }

    /**
     * 获得当前记录中指定位置的数据库字段的值，在查询语句中第一个字段的位置为1，该值为字符串或者将被转换为字符串类型
     * 不会去除前后空格
     * @param columnIndex   数据库字段在查询语句中的位置
     * @return String   该字段的值
     */
    public String getStringNoTrim(int columnIndex){
        return getStringNoTrim(columnIndex,this.isAutoDecrypt);
    }
    public String getStringNoTrim(int columnIndex, String dbColumnName){
        //return getStringNoTrim(columnIndex,this.isAutoDecrypt);
        return getStringNoTrim(null, columnIndex, dbColumnName, this.isReturnDecryptData, this.isAutoDecrypt);
    }
    public String getStringNoTrim(int columnIndex, boolean isAutoDecrypt){
        return getStringNoTrim(null, columnIndex,isAutoDecrypt);
    }
    public String getStringNoTrim(String tableName, int columnIndex, boolean isAutoDecrypt){
        return getStringNoTrim(null, columnIndex,this.isReturnDecryptData,isAutoDecrypt);
    }
    public String getStringNoTrim(String tableName, int columnIndex, boolean isReturnDecryptData, boolean isAutoDecrypt){
        return getStringNoTrim(tableName, columnIndex,null, isReturnDecryptData, isAutoDecrypt);
    }
    public String getStringNoTrim(String tableName, int columnIndex, String dbColumnName, boolean isReturnDecryptData, boolean isAutoDecrypt){
        columnIndex--;
        String s = "";
        if(!array.isEmpty() && curpos >= 0 && curpos < array.size())
        {
            Object as[] = (Object[])array.get(curpos);
            if(columnIndex>= 0 && columnIndex< as.length)
            {
                try{
                    s=as[columnIndex].toString();
                    if(dbColumnName == null || "".equals(dbColumnName)){
                        dbColumnName = columnName[columnIndex];
                    }
                    s = sqlParserUtil.decrypt(tableName, dbColumnName, s, isReturnDecryptData, isAutoDecrypt);
                }catch(Exception e){ s = ""; }
            }
        }
        s = weaver.conn.StringUtil.replace(s);
        s = Util.formatStringIfMultilang(s);
        return s ;

    }

    /**
     * 获得当前记录中指定位置的数据库字段的值，在查询语句中第一个字段的位置为1，该值为字符串或者将被转换为字符串类型
     * 不会去除前后空格
     * @param columnname   数据库字段在查询语句中的位置
     * @return String   该字段的值
     */
    public String getStringNoTrim(String columnname){
        return getStringNoTrim(columnname,this.isAutoDecrypt);
    }

    public String getStringNoTrimFromAlias(String columnname, String dbColumnName)
    {

        return getStringNoTrim(getColumnIndex(columnname), dbColumnName);
    }

    public String getStringNoTrim(String columnname, boolean isAutoDecrypt)
    {

        return getStringNoTrim(getColumnIndex(columnname),isAutoDecrypt);

    }

    public String getStringNoTrim(String tableName, String columnname){
        return getStringNoTrim(tableName, columnname,this.isAutoDecrypt);
    }
    public String getStringNoTrim(String tableName, String columnname, boolean isAutoDecrypt)
    {

        return getStringNoTrim(tableName, getColumnIndex(columnname),isAutoDecrypt);

    }

    /**
     * 获得当前记录中指定位置的数据库字段的值，在查询语句中第一个字段的位置为1，该值为字符串或者将被转换为字符串类型
     * 不会去除前后空格  columnname   数据库字段在查询语句中的位置
     * @param
     * @return String   该字段的值
     */
    public String getString(int columnIndex){
        return getString(columnIndex,this.isAutoDecrypt);
    }

    public String getString(int columnIndex, String dbColumnName){
        return getString(null, columnIndex,dbColumnName,this.isAutoDecrypt, this.isReturnDecryptData);
    }

    public String getString(int columnIndex, boolean isAutoDecrypt){
        return getString(null, columnIndex,isAutoDecrypt);
    }

    /**
     *
     * @param tableName
     * @param columnIndex
     * @param isAutoDecrypt 是否自动解密
     * @return
     */
    public String getString(String tableName, int columnIndex, boolean isAutoDecrypt){
        return getString(tableName, columnIndex, isAutoDecrypt, this.isReturnDecryptData);
    }

    /**
     *
     * @param tableName
     * @param columnIndex
     * @param isAutoDecrypt 是否自动解密
     * @param isReturnDecryptData  是否返回明文数据，为false时返回脱敏数据
     * @return
     */

    public String getString(String tableName, int columnIndex, boolean isAutoDecrypt, boolean isReturnDecryptData){
        return getString(tableName, columnIndex, null, isAutoDecrypt, isReturnDecryptData);
    }

    public String getString(String tableName, int columnIndex, String dbColumnName, boolean isAutoDecrypt, boolean isReturnDecryptData)
    {
        columnIndex--;
        String s = "";
        if(!array.isEmpty() && curpos >= 0 && curpos < array.size())
        {
            Object as[] = (Object[])array.get(curpos);
            if(columnIndex>= 0 && columnIndex< as.length)
            {
                try{
                    s=as[columnIndex].toString();
                    //解密
                    if(dbColumnName == null || "".equals(dbColumnName)){
                        dbColumnName = columnName[columnIndex];
                    }
                    s = sqlParserUtil.decrypt(tableName, dbColumnName, s, isReturnDecryptData, isAutoDecrypt);
                    s = s.trim();

                }catch(Exception e){ s = ""; }
            }
        }
        s = weaver.conn.StringUtil.replace(s);
        s = Util.formatStringIfMultilang(s);
        return s ;

    }

    /**
     * 获得当前记录中某一数据库字段的值，该值为字符串或者将被转换为字符串类型
     *
     * @param columnname   数据库字段的名称
     * @param dbColumnName  数据库字段真实名称
     * @return String   该字段的值
     */

    public String getStringFromAlias(String columnname, String dbColumnName)
    {

        return getString(getColumnIndex(columnname), dbColumnName);
    }


    public String getString(String columnname)
    {

        return getString(getColumnIndex(columnname));
    }

    /**
     * 获得当前记录中某一数据库字段的值，该值为字符串或者将被转换为字符串类型
     *
     * @param columnname   数据库字段的名称
     * @return String   该字段的值
     */
    public String getString(String columnname, boolean isAutoDecrypt)
    {

        return getString(getColumnIndex(columnname),isAutoDecrypt);
    }

    public String getString(String tableName, String columnName){
        return getString(tableName, getColumnIndex(columnName), this.isAutoDecrypt);
    }


    /**
     *
     * @param tableName
     * @param columnName
     * @param isAutoDecrypt  是否自动解密
     * @return
     */
    public String getString(String tableName, String columnName, boolean isAutoDecrypt){
        return getString(tableName, getColumnIndex(columnName),isAutoDecrypt, this.isReturnDecryptData);
    }

    /**
     * 根据字段别名获取加密数据
     * @param tableName 表名
     * @param columnName 字段别名
     * @param dbColumnName 字段名
     * @return
     */
    public String getStringFromAlias(String tableName, String columnName, String dbColumnName){
        return getString(tableName, getColumnIndex(columnName),dbColumnName,isAutoDecrypt, this.isReturnDecryptData);
    }

    /**
     *
     * @param tableName
     * @param columnName
     * @param isAutoDecrypt  是否自动解密
     * @param isReturnDecryptData  是否返回原始明文数据，如果
     * @return
     */
    public String getString(String tableName, String columnName, boolean isAutoDecrypt, boolean isReturnDecryptData){
        return getString(tableName, getColumnIndex(columnName),isAutoDecrypt,isReturnDecryptData );
    }
    /**
     * 获得当前记录中指定位置的数据库字段的值，在查询语句中第一个字段的位置为1，该值为boolean 类型
     *
     * @param columnIndex   数据库字段在查询语句中的位置
     * @return boolean   该字段的值
     */
    public boolean getBoolean(int columnIndex){
        columnIndex--;
        boolean bool=false;
        if(!array.isEmpty() && curpos>=0 && curpos<=array.size()){
            Object as[]=(Object[])array.get(curpos);
            try{
                bool=((Boolean)as[columnIndex]).booleanValue();
            }catch(Exception e){
                throw new ClassCastException();
            }
        }
        return bool;
    }

    /**
     * 获得当前记录中某一数据库字段的值，该值为boolean 类型
     *
     * @param columnName   数据库字段的名称
     * @return boolean   该字段的值
     */
    public boolean getBoolean(String columnName){
        return getBoolean(getColumnIndex(columnName));
    }

    /**
     * 获得当前记录中指定位置的数据库字段的值，在查询语句中第一个字段的位置为1，该值为int 类型
     *
     * @param columnIndex   数据库字段在查询语句中的位置
     * @return int   该字段的值
     */
    public int getInt(int columnIndex){
        return getInt(columnIndex,this.isAutoDecrypt);
    }
    public int getInt(int columnIndex, boolean isAutoDecrypt){
        return getInt(columnIndex, this.isReturnDecryptData, isAutoDecrypt);
    }
    public int getInt(int columnIndex, boolean isReturnDecryptData, boolean isAutoDecrypt){
        columnIndex--;
        int integer=-1;
        if(!array.isEmpty() && curpos >= 0 && curpos < array.size())
        {
            Object as[] = (Object[])array.get(curpos);
            if(columnIndex >= 0 && columnIndex < as.length)
            {
                if(as[columnIndex]!=null){
                    //integer = Util.getIntValue(as[columnIndex].toString().trim(),-1);
                    String s = as[columnIndex].toString().trim();
                    //解密
                    s = sqlParserUtil.decrypt(this.fieldTableMap.get(columnName[columnIndex]), columnName[columnIndex], s,isReturnDecryptData,isAutoDecrypt);
                    integer = Util.getIntValue(s,-1);
                }
            }
        }
        return integer;
    }

    /**
     * 获得当前记录中某一数据库字段的值，该值为int 类型
     *
     * @param columnname   数据库字段的名称
     * @return int   该字段的值
     */
    public int getInt(String columnname){
        return getInt(getColumnIndex(columnname),this.isAutoDecrypt);
    }
    public int getInt(String columnname,boolean isAutoDecrypt){
        return getInt(getColumnIndex(columnname),isAutoDecrypt);
    }
    /**
     * 获得当前记录中指定位置的数据库字段的值，在查询语句中第一个字段的位置为1，该值以二进制输出流形式输出 InputStream
     *
     * @param columnIndex  数据库字段在查询语句中的位置
     * @return InputStream   该字段的输出
     */
    public InputStream getInputStream(int columnIndex)
    {
        BufferedInputStream bis=null;
        if(!array.isEmpty()&&curpos>=0 && curpos <= array.size())
        {
            Object as[]=(Object[])array.get(curpos);
            if(columnType[columnIndex]==Types.LONGVARCHAR)
            {
                byte inputByte[]=new byte[as[columnIndex].toString().length()];
                inputByte=as[columnIndex].toString().getBytes();

                bis=new BufferedInputStream(new ByteArrayInputStream(inputByte));
            }
        }
        else
        {
            throw new ClassCastException();
        }
        return bis;
    }

    /**
     * 获得当前记录中某一数据库字段的值，该值以二进制输出流形式输出 InputStream
     *
     * @param columnName   数据库字段的名称
     * @return InputStream   该字段的输出
     */
    public InputStream getInputStream(String columnName){
        return  getInputStream(getColumnIndex(columnName));
    }

    /**
     * 获得当前记录中指定位置的数据库字段的值，在查询语句中第一个字段的位置为1，该值为float 类型
     *
     * @param columnIndex   数据库字段在查询语句中的位置
     * @return float   该字段的值
     */
    public float getFloat(int columnIndex){
        return getFloat(columnIndex,this.isAutoDecrypt);
    }
    public float getFloat(int columnIndex, boolean isAutoDecrypt){
        return getFloat(columnIndex,this.isReturnDecryptData,isAutoDecrypt);
    }
    public float getFloat(int columnIndex, boolean isReturnDecryptData, boolean isAutoDecrypt){
        columnIndex--;
        float f=0.0f;
        if(!array.isEmpty() && curpos>=0 && curpos<=array.size()){
            Object as[]=(Object[])array.get(curpos);
            try{
                String s = as[columnIndex].toString();
                //解密
                s = sqlParserUtil.decrypt(this.fieldTableMap.get(columnName[columnIndex]), columnName[columnIndex], s,isReturnDecryptData,isAutoDecrypt);
                f=Util.getFloatValue(s,-1);
                //f=Util.getFloatValue(as[columnIndex].toString(),-1);
            }catch(ClassCastException cce){
                throw new ClassCastException();
            }
        }
        return f;
    }

    /**
     * 获得当前记录中某一数据库字段的值，该值为float 类型
     *
     * @param columnName   数据库字段的名称
     * @return float   该字段的值
     */
    public  float getFloat(String columnName){
        return getFloat(this.getColumnIndex(columnName));
    }

    /**
     * 获得当前记录中指定位置的数据库字段的值，在查询语句中第一个字段的位置为1，该值为double 类型
     *
     * @param columnIndex   数据库字段在查询语句中的位置
     * @return double   该字段的值
     */
    public double getDouble(int columnIndex){
        return getDouble(columnIndex,this.isAutoDecrypt);
    }
    public double getDouble(int columnIndex,boolean isAutoDecrypt){
        return getDouble(columnIndex,this.isReturnDecryptData,isAutoDecrypt);
    }
    public double getDouble(int columnIndex,boolean isReturnDecryptData,boolean isAutoDecrypt){
        columnIndex--;
        double d=0.0;
        if(!array.isEmpty() && curpos>=0 && curpos <= array.size()){
            Object as[]=(Object[])array.get(curpos);
            try{
                //d=Util.getDoubleValue(as[columnIndex].toString(),-1);
                String s = as[columnIndex].toString().trim();
                //解密
                s = sqlParserUtil.decrypt(this.fieldTableMap.get(columnName[columnIndex]), columnName[columnIndex], s, isReturnDecryptData, isAutoDecrypt);
                d=Util.getDoubleValue(s,-1);
            }catch(ClassCastException cce){
                throw new ClassCastException();
            }
        }
        return d;
    }

    /**
     * 获得当前记录中某一数据库字段的值，该值为double 类型
     *
     * @param columnName   数据库字段的名称
     * @return double   该字段的值
     */
    public double getDouble(String columnName){
        return getDouble(columnName,this.isAutoDecrypt);
    }
    public double getDouble(String columnName,boolean isAutoDecrypt){
        return getDouble(getColumnIndex(columnName),isAutoDecrypt);
    }

    /**
     * 获得当前记录中指定位置的数据库字段的值，在查询语句中第一个字段的位置为1，该值以日期类型输出
     *
     * @param columnIndex  数据库字段在查询语句中的位置
     * @return Date   该字段的值
     */
    public Date getDate(int columnIndex){
        columnIndex--;
        Date date=null;
        if(!array.isEmpty() && curpos>=0 && curpos<=array.size()){
            Object as[]=(Object[])array.get(curpos);
            try{
                if(as[columnIndex] instanceof String){
                    Timestamp sqlDate =  Timestamp.valueOf(as[columnIndex].toString());
                    return new Date(sqlDate.getTime());
                }else if(as[columnIndex] instanceof java.sql.Date){
                    date=(java.sql.Date)as[columnIndex];
                    if(date != null){
                        Timestamp sqlDate = new Timestamp(date.getTime());
                        return new Date(sqlDate.getTime());
                    }
                }else{
                    date=(Date)as[columnIndex];
                }
            }catch(Exception e){
                throw new ClassCastException();
            }
        }
        return date;
    }

    /**
     * 获得当前记录中某一数据库字段的值，该值以日期类型输出
     *
     * @param columnName   数据库字段的名称
     * @return Date   该字段的值
     */
    public Date getDate(String columnName){
        return getDate(getColumnIndex(columnName));
    }


    public String getBlobStr(int columnIndex){
        columnIndex--;
        String rst = null;
        if(!array.isEmpty() && curpos>=0 && curpos<=array.size()){
            Object as[]=(Object[])array.get(curpos);
            try{
                /* if(as[columnIndex] instanceof Blob){*/
                if(as[columnIndex] instanceof byte[]) {
                    rst = new String((byte[]) as[columnIndex], "UTF-8");
                }
                else if(as[columnIndex] instanceof Blob)
                {
                    Blob b=(Blob)as[columnIndex];
                    InputStream is=b.getBinaryStream();
                    byte[] bytes = new byte[0];
                    bytes = new byte[is.available()];
                    is.read(bytes);
                    rst = new String(bytes);
                }
                else{
                    rst = String.valueOf(as[columnIndex]);
                }
                // rst = getTextFromBlob((byte[])as[columnIndex]);
               /* }else{
                    rst = String.valueOf(as[columnIndex]);
                }*/
            }catch(Exception e){
                throw new ClassCastException();
            }
        }
        return rst;
    }

    public String getBlobStr(String columnName){
        return getBlobStr(getColumnIndex(columnName));
    }

   /* private String getTextFromBlob(byte[] blob) {
        int i = 1;
        byte btArr[] = new byte[0];
        try {
            while (i < blob.length) {
                byte[] bytes = blob.getBytes(i, 1024);
                btArr = ArrayUtils.addAll(btArr, bytes);
                i += 1024;
            }
            return new String(btArr, "UTF-8");
        } catch (Exception e) {
           e.printStackTrace();
        }
        return null;
    }*/
    /**
     * 获得当前记录中指定位置的数据库字段的值，在查询语句中第一个字段的位置为1，该值以二进制输出流形式输出 InputStream
     *
     * @param columnIndex  数据库字段在查询语句中的位置
     * @return InputStream   该字段的输出
     */
    public InputStream getBinaryStream(int columnIndex){
        columnIndex--;
        InputStream is=null;
        if(!array.isEmpty() && curpos>=0 && curpos <= array.size()){
            Object[] as=(Object[])array.get(curpos);
            try{
                if(databaseType.equals("oracle")||databaseType.equals("sqlserver")) is=((Blob)as[columnIndex]).getBinaryStream();
                else is = (InputStream)as[columnIndex] ;
            }catch(Exception e){
                writeLog(e) ;
                throw new ClassCastException();
            }
        }
        return is;
    }

    /**
     * 获得当前记录中某一数据库字段的值，该值以二进制输出流形式输出 InputStream
     *
     * @param columnName   数据库字段的名称
     * @return InputStream   该字段的输出
     */
    public InputStream getBinaryStream(String columnName){
        return getBinaryStream(getColumnIndex(columnName));
    }

    /**
     * 获得由存储过程返回的Flag 值，该方法当前请无使用
     *
     * @return int   存储过程返回的Flag 值
     */
    public int getFlag()
    {
        if(flag==0)
            flag=1;
        return flag;
    }

    public void setFlag(int flag) {
        this.flag = flag;
    }

    /**
     * 获得由存储过程返回的Msg 信息，该方法当前请无使用
     *
     * @return String   存储过程返回的Msg 信息
     */
    public String getMsg()
    {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
    /**
     * 将查询结果的游标从当前位置移至第一条记录之前。
     *
     */
    public void beforFirst()
    {
        curpos = -1;
    }

    /**
     * 将查询结果的游标从当前位置移至第一条记录。
     *
     * @return boolean   如果第一条记录存在，返回true，否则返回false
     */
    public boolean first()
    {
        if(array.isEmpty())
        {
            return false;
        } else
        {
            curpos = 0;
            return true;
        }
    }

    /**
     * 将查询结果的游标从当前位置移至最后一条记录。
     *
     * @return boolean   如果最后一条记录存在，返回true，否则返回false
     */
    public boolean last()
    {
        if(array.isEmpty())
        {
            return false;
        } else
        {
            curpos = array.size() - 1;
            return true;
        }
    }

    /**
     * 将查询结果的游标从当前位置移至最后一条记录之后。
     *
     */
    public void afterLast()
    {
        curpos = array.size();
    }

    /**
     * 将查询结果的游标从当前位置移至下一个位置，游标最初位于第一条记录之前。
     *
     * @return boolean   如果下一个位置有值，返回true，否则返回false
     */
    public boolean next()
    {
        if(array.isEmpty())
            return false;
        boolean flag1 = true;
        if(curpos < array.size() - 1)
        {
            curpos++;
            return true;
        } else
        {
            return false;
        }
    }

    /**
     * 将查询结果的游标从当前位置移至上一个位置。
     *
     * @return boolean   如果上一个位置有值，返回true，否则返回false
     */
    public boolean previous()
    {
        if(array.isEmpty())
            return false;
        if(curpos > 0 && curpos <= array.size())
        {
            curpos--;
            return true;
        } else
        {
            return false;
        }
    }

    /**
     * 将查询结果的游标从当前位置移至指定位置，游标第一条记录的位置为1 。
     *
     * @return boolean   如果指定位置有值，返回true，否则返回false
     */
    public boolean absolute(int i)
    {
        if(array.isEmpty())
            return false;
        if(i >= 0 && i < array.size())
        {
            curpos = i;
            return true;
        } else
        {
            return false;
        }
    }

    //获取数据库原始类型,有oracle、mysql、sqlserver、obmysql、ob、st、dm、jc、gs、nt、db2、pg、hg、ux、og
    public String getOrgindbtype() {
        if(poolname==null||GCONST.getServerName().equals(poolname)||"".equals(poolname)){
            return pool.getOrgindbtype();
        }
        return this.getOrgindbtype(poolname);
    }


    public String getOrgindbtype(String poolname) {
        BaseDataSource bds = ExternalDataSourceManager.getExternalDS(poolname);
        if(bds==null){
            return this.getDBType(poolname);
        }
        return ExternalDataSourceManager.getOrgindbtypeByType(bds.getType());
    }

    //获取数据库类型,有oracle、mysql、sqlserver、postgresql
    public String getDBType() {

        return getDBType(null) ;
    }


    public String getDBType(String poolname) {
        String dbtype = "";
        if(poolname==null||"".equals(poolname)){
            dbtype = pool.getDbtype();
        }else{
            dbtype = getDBTypeByPoolName(poolname);
        }
        return dbtype ;

    }

    public String getDBTypeByPoolName(String poolname) {
       // if(conn!=null){
         //   return conn.getDBType();
       // }else{
            WeaverConnection conn1 = null;
            try{
                conn1 = pool.getConnection(poolname);
                return conn1.getDBType();
            }finally{
                pool.returnConnection(poolname, conn1);
            }
      //  }

    }


    /**
     * 获得查询的字段在字段排列中的位置
     *
     */
    private int getColumnIndex(String columnname){
        for(int i1=0;i1<columnName.length;i1++)
            if(columnName[i1].equalsIgnoreCase(columnname))
                return i1+1;
        return -1;
    }
    private String sqlTmp = "";
    private long resultSize = 0l;

    /**
     * 保存字段和表之间的映射关系
     */
    private Map<String, String> fieldTableMap = new ConcurrentHashMap<String, String>();
    /**
     * 解析查询结果
     *
     */
    public void parseResultSet(ResultSet resultset) throws Exception{
        init() ;
        ResultSetMetaData resultsetmetadata = resultset.getMetaData();
        int i1 = resultsetmetadata.getColumnCount();
        columnName=new String[i1];
        columnType=new int[i1];
        columnIndex=new int[i1];
        columnDisplaySize=new int[i1];
        columnTypeName = new String[i1];
        String[] dbtype=new String[]{"ob","nt"};
        for(int i2=0;i2<i1;i2++){
            if (DBConstant.DB_TYPE_MYSQL.equals(getDBType(this.poolname))||Arrays.asList(dbtype).contains(getOrgindbtype())) {
                columnName[i2]=resultsetmetadata.getColumnLabel(i2+1);
            } else {
                columnName[i2]=resultsetmetadata.getColumnName(i2+1);
            }
            if( resultsetmetadata.getTableName(i2+1) != null) {
                fieldTableMap.put(columnName[i2], resultsetmetadata.getTableName(i2 + 1));
            }
            columnType[i2]=resultsetmetadata.getColumnType(i2+1);
            columnTypeName[i2]=resultsetmetadata.getColumnTypeName(i2+1);
            columnIndex[i2]=i2+1;
            columnDisplaySize[i2]=resultsetmetadata.getColumnDisplaySize(i2+1);
        }
        int j1;
        for(j1 = 0; resultset.next(); j1++)
        {
            Object as[] = new Object[i1];
            for(int k1 = 1; k1 <= i1; k1++){
                if(MonitorSqlUtil.isInterceptSqlMem(resultSize)){
                    MonitorRecordMemUtil.putLog(this.sqlTmp,array.size(),resultSize);
                    MonitorSqlUtil.logq.offer("此sql查询的结果集过大，已被拦截>>"+sqlTmp);
                    new BaseBean().writeLog("此sql查询的结果集过大，已被拦截>>"+sqlTmp);
                    throw new RuntimeException("此sql查询的结果集过大，已被拦截>>"+sqlTmp);
                }

                Object tempobj = resultset.getObject(k1) ;
                if( tempobj == null)  {
                    as[k1 - 1] = "";
                    //as[k1 - 1] = "ob".equalsIgnoreCase(getOrgindbtype())?null:"";
                }
                else if(columnType[k1 - 1]==Types.CLOB||columnType[k1 - 1]==Types.NCLOB)
                {
                    Clob clob=null;
                    try
                    {
                        //modified by lrf for E8 将数据库的clob 内容转换为 utf-8字符串
                        if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                            String tempobjStr = EncodingUtils.toUTF8(tempobj);
                            as[k1 - 1] = tempobjStr;
                            resultSize+= tempobjStr.getBytes().length;
                        }else{
                            String tempobjStr = EncodingUtils.ClobToString(tempobj);
                            as[k1 - 1] = tempobjStr;
                            resultSize+= tempobjStr.getBytes().length;
                        }

                  /*  clob=(Clob)tempobj ;
                    if(clob!=null) {
                        String readline = "" ;
                        StringBuffer clobStrBuff = new StringBuffer("") ;
                        BufferedReader clobin = new BufferedReader(clob.getCharacterStream());
                        while ((readline = clobin.readLine()) != null) clobStrBuff = clobStrBuff.append(readline) ;
                        clobin.close() ;
                        as[k1 - 1] = clobStrBuff.toString() ;
                    }
                    else as[k1 - 1] = "";*/
                    }catch(Exception se){as[k1 - 1] = "";}
                }else if (columnType[k1 - 1]==Types.BLOB){
                    as[k1 - 1] = tempobj ;
                    resultSize+= (tempobj+"").getBytes().length;
                }else if (columnType[k1 - 1]==Types.DECIMAL){ //Decimal以字符串的形式保存精确的原始数值
                    String tmp = String.valueOf(tempobj);
                    if(tmp!=null&&tmp.indexOf("e")<0&&tmp.indexOf("E")<0){ //如果不是科学计数法
                        as[k1 - 1] = formatDecimal(tmp);
                    }else{
                        as[k1 - 1] = formatDouble(Double.valueOf(tmp));
                    }
                    resultSize+= tmp.getBytes().length;
                }else if (columnType[k1 - 1]==Types.NUMERIC){
                    String tmp = String.valueOf(tempobj);
                    if(tmp!=null&&tmp.indexOf("e")<0&&tmp.indexOf("E")<0){ //如果不是科学计数法
                        as[k1 - 1] = formatDecimal(tmp);
                    }else{
                        as[k1 - 1] = formatDouble(Double.valueOf(tmp));
                    }
                    //String ss = formatDouble(Double.valueOf(String.valueOf(tempobj)));
//            	double tt = Double.valueOf(String.valueOf(tempobj));
                    //as[k1 - 1] = ss;
                    resultSize+= (as[k1 - 1]+"").getBytes().length;
//            	}else{
//            		as[k1 - 1] =tempobj;
//            	}
                }else if(columnType[k1 - 1]==Types.TIMESTAMP){
                    String tempobjStr = resultset.getTimestamp(k1).toString();
                    as[k1 - 1] = tempobjStr;
                    resultSize+= tempobjStr.getBytes().length;
                }
                //modified by lrf for E8 将数据库的字段内容转换为 utf-8字符串
                else{
                    if(EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY){
                        String tempobjStr = EncodingUtils.toUTF8(tempobj) ;
                        as[k1 - 1] = tempobjStr;
                        resultSize+= tempobjStr.getBytes().length;
                    }else{
                        as[k1 - 1] = tempobj ;
                        resultSize+=(tempobj+"").getBytes().length;
                    }
                }
            }
            array.add(as);
        }
        try{
            if(resultSize>MonitorSqlUtil.writeMemLog*1024*1024l){
                MonitorRecordMemUtil.putLog(this.sqlTmp,array.size(),resultSize);
            }
        }catch (Exception e) {
            // TODO: handle exception
        }

    }
    private static String formatDouble(double d) {
        String data = String.valueOf(d);
        if(data.length()<8) return data;  //小于8位长度不会存在显示为科学计数法问题
        NumberFormat nf = NumberFormat.getInstance();
        //设置保留多少位小数
        nf.setMaximumFractionDigits(20);
        // 取消科学计数法
        nf.setGroupingUsed(false);
        //返回结果
        return nf.format(d);
    }

    /**
     * 对decimal数值做兼容处理,实现保留精度,并避免小数位后面尾数0过多,显示过长.<br>
     * @param decimal 以字符串形式在数据库存储的精确数据<br>
     * @return
     */
    private static String formatDecimal(String decimal){
        if(decimal == null){
            return "null";
        }
        if(decimal.length()<8){  //小于8位长度不会存在读取显示精度丢失问题
            return decimal;
        }
        decimal = decimal.trim();
        if("".equals(decimal)){
            return "";
        }
        if(decimal.indexOf(".")<0){ //仅整数时,默认添加返回两个小数位00
            // return decimal+".00";
            return decimal;
        }else{
            if(decimal.endsWith(".")){//整数位后仅有一个小数点,默认添加返回两个小数位00
                // return decimal+"00";
                return decimal;
            }
            String strs[] = decimal.split("\\.");
            String i = strs[0];
            String d = strs[1];
            if(d.length()==1){ //仅有一位小数,小数位默认添加一个0
                // return i+"."+d+"0";
                if("0".equals(d)){
                    return i;
                }
                return decimal;
            }else{  //两位以上小数，去掉末尾的0
                for(int j=d.length()-1;j>1;j--){
                    if(d.charAt(j)=='0'){
                        d = d.substring(0,j);
                    }else{  //遇到非0位截止
                        break;
                    }
                }
                if("00".equals(d)){ // 跟之前保持一致，如果是12.00返回12
                    return i;
                }
                return i+"."+d;
            }
        }
    }

    /**
     * 获取数据库链接
     *
     */
    private boolean getConnection(String poolname)
    {
        try
        {
            if(poolname != null )   conn=pool.getConnection(poolname);
            else conn=pool.getConnection();

            if(conn != null )  return true;
            else return false  ;
        }
        catch(Exception exception)
        {
            writeLog(exception) ;
        }
        return false;
    }

    /**
     * 归还数据库链接
     *
     */
    private void givebackConnection(String poolname,String sql)
            throws SQLException
    {
        if(MonitorSqlUtil.isOnlySelect(sql)) {
            if(conn != null ){
                if(poolname != null )   pool.returnConnectionOntCommit(poolname  , conn);
                else  pool.returnConnectionOntCommit(null,conn);
            }
        }else {
            givebackConnection(poolname);
        }
    }
    /**
     * 归还数据库链接
     *
     */
    private void givebackConnection(String poolname)
            throws SQLException
    {
        if(conn != null )
        {
            if(poolname != null )   pool.returnConnection(poolname  , conn);
            else  pool.returnConnection(conn);
        }
    }

    /**
     * 初始化
     *
     */
    public void init()
    {
        curpos = -1;
        flag = 1;
        msg = "";
        array.clear();
        resultSize = 0l;
    }

    /**
     * 解析存储过程参数
     *
     */
    private void parseArgument(String s) {
        boolean needTransCode = false;
        if (poolname == null || GCONST.getServerName().equals(poolname) || EncodingUtils.containsNativeDB(poolname) || "".equals(poolname)) {
            if (EncodingUtils.encodingStrategy == EncodingUtils.UNICODEENCODING_STRATEGY) {
                needTransCode = true;
            }
        }
        int i = 0;
        int j = 0;
        if (s.trim().equals("")) {
            args = new String[0];
            return;
        }
        for (j = 0; j < s.length(); j++)
            if (s.charAt(j) == separator)
                i++;

        args = new String[i + 1];
        j = 0;
        i = 0;
        databaseType = getDBType() ;
        while ((j = s.indexOf(separator)) != -1) {
            // fix by caoyun 支持Mysql数字类型传入null
            String a = s.substring(0, j);
            if (needTransCode) {
                a = EncodingUtils.toUNICODE(a);
            }
            if (DBConstant.DB_TYPE_MYSQL.equals(databaseType)) {
                if (StringUtils.isEmpty(a)) {
                    a = null;
                }
            }
            args[i++] = a;
            s = s.substring(j + 1);
        }
        if (needTransCode) {
            s = EncodingUtils.toUNICODE(s);
        }
        if (DBConstant.DB_TYPE_MYSQL.equals(databaseType)) {
            if (StringUtils.isEmpty(s)) {
                s = null;
            }
        }
        args[i] = s;
    }


    public boolean isChecksql() {
        return checksql;
    }

    public void setChecksql(boolean checksql) {
        this.checksql = checksql;
    }


    public RecordSetData getData(){
        RecordSetData data = new RecordSetData();
        Field[] fields = data.getClass().getDeclaredFields();
        Class clazz = data.getClass();
        Field field = null;
        try {
            field = clazz.getDeclaredField("array");
            field.setAccessible(true);
            field.set(data, array);

            field = clazz.getDeclaredField("columnName");
            field.setAccessible(true);
            field.set(data, columnName);

            field = clazz.getDeclaredField("columnIndex");
            field.setAccessible(true);
            field.set(data, columnIndex);

            field = clazz.getDeclaredField("columnTypeName");
            field.setAccessible(true);
            field.set(data, columnTypeName);

            field = clazz.getDeclaredField("columnDisplaySize");
            field.setAccessible(true);
            field.set(data, columnDisplaySize);

            field = clazz.getDeclaredField("columnType");
            field.setAccessible(true);
            field.set(data, columnType);

            field = clazz.getDeclaredField("databaseType");
            field.setAccessible(true);
            field.set(data, databaseType);

            field = clazz.getDeclaredField("orgindbtype");
            field.setAccessible(true);
            field.set(data, this.getOrgindbtype());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }
	
	/**
     * 获取当前数据库的主要版本
     * dme
     * @return
     */
    public int getDatabaseMajorVersion() {
        if (conn == null){
            conn = pool.getConnection();
        }
        try {
            DatabaseMetaData metaData = conn.getMetaData();
            int version = metaData.getDatabaseMajorVersion();
            return version;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 获取当前数据库的次要版本
     * dme
     * @return
     */
    public int getDatabaseMinorVersion() {
        if (conn == null){
            conn = pool.getConnection();
        }
        try {
            DatabaseMetaData metaData = conn.getMetaData();
            int version = metaData.getDatabaseMinorVersion();
            return version;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 获得当前数据库的详细版本
     * @return
     */
    public String getDatabaseProductVersion() {
        if (conn == null){
            conn = pool.getConnection();
        }
        try {
            DatabaseMetaData metaData = conn.getMetaData();
            String version = metaData.getDatabaseProductVersion();
            return version;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取存储过程输出参数
     * @return
     */
    public Map<String,Object> getOutput(){
        return output;
    }



    public void setDatabaseType(String databaseType) {
        this.databaseType = databaseType;
    }

    public Vector getArray() {
        return array;
    }

    public void setArray(Vector array) {
        this.array = array;
    }

    public void setColumnName(String[] columnName) {
        this.columnName = columnName;
    }

    public void setColumnType(int[] columnType) {
        this.columnType = columnType;
    }


    public long getLostTime() {
        return lostTime;
    }

    public void setLostTime(long lostTime) {
        this.lostTime = lostTime;
    }

    public String getExceptionMsg() {
        return exceptionMsg;
    }

    public void setExceptionMsg(String exceptionMsg) {
        this.exceptionMsg = exceptionMsg;
    }

    public int[] getColumnDisplaySize() {
        return columnDisplaySize;
    }

    public void setColumnDisplaySize(int[] columnDisplaySize) {
        this.columnDisplaySize = columnDisplaySize;
    }

    public int[] getColumnIndex() {
        return columnIndex;
    }

    public void setColumnIndex(int[] columnIndex) {
        this.columnIndex = columnIndex;
    }

    public int getUpdateCount() {
        return updateCount;
    }

    public void setUpdateCount( int updateCount ) {
        this.updateCount = updateCount;
    }

    public long getResultSize() {
        return resultSize;
    }

    public void setResultSize(long resultSize) {
        this.resultSize = resultSize;
    }

    @Override
    public String[] getColumnTypeName() {
        return columnTypeName;
    }

    @Override
    public void setColumnTypeName(String[] columnTypeName) {
        this.columnTypeName = columnTypeName;
    }

    public int[] getBatchCounts() {
        return batchCounts;
    }

    public void setBatchCounts(int[] batchCounts) {
        this.batchCounts = batchCounts;
    }

    private int[] batchCounts;

    private long lostTime;
    private int curpos;
    private int flag;
    private String msg;
    public static char separator = Util.getSeparator() ;
    private Vector array;

    /**
     * 存储过程输出参数集合
     */
    private Map<String,Object> output;

    private String columnName[];
    private int columnDisplaySize[];
    private int columnIndex[];
    private int columnType[];
    private String columnTypeName[];
    private String args[];
    private ConnectionPool pool=ConnectionPool.getInstance();
    private WeaverConnection conn;
    private boolean bSuccess;
    private String databaseType ;
    private boolean checksql;//是否检查sql
    private int updateCount;



    /**
     * 不执行敏感词过滤
     * @param b
     */
    public void setNoSensitveFilter(boolean b) {
        sqlParserUtilForSensitvie.setNoSensitiveFilter(true);
    }
}
