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();