2

所以基本上,我使用的是 Java、JRI(Java 的 R)和 RJDBC(在 JRI 的帮助下),它们都运行得很好。现在,我想让我的程序尽可能地万无一失。假设字符串 SQL_command 是某种垃圾,并不是真正有效的 SQL 语句。在这种情况下...

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

......应该出错了。我的想法是这样的:如果 R 命令失败,R 中会有某种输出。如果一切正确,则没有输出。但是我怎样才能捕捉到可能的输出呢?

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

提前致谢!

4

2 回答 2

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)
于 2014-10-12T18:48:24.647 回答
0

根据org.rosuda.JRI.Rengine.eval(String)方法的文档,如果出现问题,null将返回。该方法不会抛出任何类型的,Exception因此它似乎没有提供任何确定问题原因的方法。

org.rosuda.REngine.parseAndEval(String)方法确实抛出了几种Exception类型,REngineException并且REXPMismatchException可能会提供更多关于失败的解释,但文档并不清楚为什么以及何时会抛出这些类型。

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

于 2014-10-12T18:09:19.070 回答