commons-exec调用达梦disql.exe的若干问题

commons-exec调用达梦disql.exe的若干问题

问题一、在windows 平台disql登陆不了数据库

//拼接disql登陆命令的代码片段

     String disql = params.getDisqlPath();
        if (SystemUtils.IS_OS_WINDOWS){
            dmfldr = disql+" %s/%s@%s:%s  `%s ";
        }else {
            dmfldr = disql+" '%s/%s@%s:%s' '`%s' ";
        }
        String cmd = String.format(dmfldr,
                params.getUsername(),
                params.getPassword(),
                params.getHost(),
                params.getPort(),
                newsql.getAbsolutePath());
        return cmd;


//执行命令的代码片段
protected boolean isExecSucessAndPrintLog(Executor exec, String command, ByteArrayOutputStream outputStream) 
			throws ExecuteException, IOException
	{
		CommandLine commandline = CommandLine.parse(command);
		System.out.println("cmd:"+commandline);
		int result = exec.execute(commandline, environment);
		System.out.println(getCorrectString(outputStream, commandline.getArguments()));
		System.out.println();
		return result == 0 ? true : false;
	}

报错:日志一直打印disql使用空用户名和密码登陆数据库,连接不上数据库。

解决方法:int result = exec.execute(commandline, environment); 中environment 传递了一个“空”hashmap,直接传递null进入方法,就解决了。

问题二、在windows平台disql不能执行UTF-8 编码的SQL文件

解决方法:将SQL文件在windows平台转换为GBK编码。且原来SQL文件需要是UTF-8 无BOM格式

File newsql = null;
        try {
            newsql = File.createTempFile("dmexec", ".sql");
            newsql.deleteOnExit();
            String sqlContent = FileUtils.readFileToString(new File(sqlPath),"UTF-8");
            StringBuilder newSQLContent = new StringBuilder();
            newSQLContent.append( params.isOnErrorExit()?"whenever sqlerror exit 1 \r\n":"");
            newSQLContent.append(sqlContent);
            newSQLContent.append(" \r\n quit;");
            String temp = newSQLContent.toString();
            byte[] bytes = null;
            if(SystemUtils.IS_OS_WINDOWS) {
                bytes = temp.getBytes("GBK");
            }else {
                bytes = temp.getBytes("UTF-8");
            }
            FileUtils.writeByteArrayToFile(newsql, bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }

问题三、在Linux 平台disql 执行后输出中文日志乱码

解决方法:需要在环境变量指定LANG=en_US.UTF-8

    @Override
    public void initProcessEnvironment(ConfigParams params) {
        if (SystemUtils.IS_OS_LINUX) {
            env = new HashMap<String, String>();
            env.put("LD_LIBRARY_PATH", this.params.getPsqllib());
            env.put("LANG", "en_US.UTF-8");
        }
    }

问题四、在windows 平台调用PG数据库psql时登陆不了数据库

原因:windows 平台不能使用int result = exec.execute(commandline, environment); 中environment 传递PGPASSWORD、PGUSER等环境变量,需要传递为null。

解决方法:把命令拼接程bat文件执行

 String configOnErrorExit = this.params.isOnErrorExit() ? " -v \"ON_ERROR_STOP=1\"" : "";
        String cmdStr = String.format("%s -h %s -p %s -U %s -d %s -f %s",
                this.params.getPsqlPath(),
                params.getHost(),
                params.getPort(),
                params.getUsername(),
                params.getDbName(),
                sqlPath);
        cmdStr = cmdStr + configOnErrorExit;
        File script = null;
        try {
            script = File.createTempFile("exec", ".bat");
            script.deleteOnExit();
            String batTemplate =        "set PGPASSWORD=%s\r\n";
            batTemplate = batTemplate + "set PGUSER=%s\r\n";
            batTemplate = batTemplate + "set PGCLIENTENCODING=%s\r\n";
            String scriptContent = String.format(batTemplate,
                    this.params.getPassword(),
                    this.params.getUsername(),
                    AppConfigUtils.getEncoding()
                    );
            scriptContent = scriptContent + cmdStr;
            FileUtils.writeStringToFile(script,scriptContent);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return script.getAbsolutePath();
posted @ 2020-12-18 13:36  wangzhen3798  阅读(381)  评论(0编辑  收藏  举报