所以基本上,我使用Java,JRI(R代表Java)和RJDBC(借助JRI),这些都运行良好。 现在,我想让我的程序尽可能万无一失。让我们说,字符串SQL_command是某种垃圾而不是真正有效的SQL语句。在那种情况下......
re.eval("sql_data <- dbGetQuery(conn, \"" + SQL_command + "\")");
......应该出问题。 我的想法是这样的:如果R命令失败,R中会有某种输出。如果每一个都正确,没有输出。但是我如何捕获可能的输出呢?
请记住,我的问题更多的是如何捕获无效的R语句,因此对于可能的解决方案的任何其他建议也表示赞赏。 R输出不一定重要,但无论如何它可能都很有趣。
提前致谢!
答案 0 :(得分:2)
我建议直接在R中捕获由于R代码导致的(可能的)异常。因此,如果我怀疑某个命令可能会出错,我会使用try
函数在R.这方面的东西:
REXP y = re.eval("sql_data <- try(dbGetQuery(conn, \"" + SQL_command + "\"),silent=TRUE)");
REXP x = re.eval("class(sql_data)");
if ((x.asString()).equals("try-error")) {
System.out.println(y.asString());
// do something to catch the exception
} else {
// do normal stuff
}
这样你也可以显示R错误。
这里有一些可重现的(除了数据库凭据之外)代码,它首先尝试执行有效的查询语句,然后再执行无效的查询语句。
import java.io.*;
import org.rosuda.JRI.*;
public class Prova {
public static void main(String[] args) {
String[] commands = {"a<-try(dbGetQuery(conn,'show tables'))","a<-try(dbGetQuery(conn,'SS'))"};
Rengine re=new Rengine (new String [] {"--vanilla"}, false, null);
re.eval("require(RMySQL)");
re.eval("conn<-dbConnect(MySQL(),user='xxx',password='xxx',dbname='xxx')");
for (int i=0;i<2;i++) {
REXP y = re.eval(commands[i]);
REXP x = re.eval("class(a)");
if ((x.asString()).equals("try-error")) {
System.out.println(y.asString());
} else {
System.out.println(x.asString());
}
}
re.end();
}
}
输出:
data.frame
Error in mysqlExecStatement(conn, statement, ...) :
RS-DBI driver: (could not run statement: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SS' at line 1)
答案 1 :(得分:0)
根据the documentation for the org.rosuda.JRI.Rengine.eval(String)
method,如果出现问题,我们会退回null
。该方法不会抛出任何类型的Exception
,因此它似乎无法提供任何确定问题原因的方法。
org.rosuda.REngine.parseAndEval(String)
method确实会抛出几种Exception
类型,REngineException
和REXPMismatchException
,这可能会提供更多失败的解释,但文档并不清楚具体原因和什么时候会被扔掉。
因此,您可以做的最好的事情是检查null
返回值。