JRI - 如何定位R中的错误

时间:2014-10-12 16:41:55

标签: java mysql r jri rjdbc

所以基本上,我使用Java,JRI(R代表Java)和RJDBC(借助JRI),这些都运行良好。 现在,我想让我的程序尽可能万无一失。让我们说,字符串SQL_command是某种垃圾而不是真正有效的SQL语句。在那种情况下......

    re.eval("sql_data <- dbGetQuery(conn, \"" + SQL_command + "\")");

......应该出问题。 我的想法是这样的:如果R命令失败,R中会有某种输出。如果每一个都正确,没有输出。但是我如何捕获可能的输出呢?

请记住,我的问题更多的是如何捕获无效的R语句,因此对于可能的解决方案的任何其他建议也表示赞赏。 R输出不一定重要,但无论如何它可能都很有趣。

提前致谢!

2 个答案:

答案 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类型,REngineExceptionREXPMismatchException,这可能会提供更多失败的解释,但文档并不清楚具体原因和什么时候会被扔掉。

因此,您可以做的最好的事情是检查null返回值。