首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Octave:如何从Java ResultSet对象中检索数据?

Octave:如何从Java ResultSet对象中检索数据?
EN

Stack Overflow用户
提问于 2019-04-01 17:15:35
回答 2查看 181关注 0票数 1

我需要向Octave实例提供从Oracle数据库检索到的数据。

我已经在我的Octave实例中实现了一个OJDBC连接,现在我可以将Oracle数据库中的数据放入Octave中的Java ResultSet对象(取自:https://lists.gnu.org/archive/html/help-octave/2011-08/msg00250.html):

代码语言:javascript
复制
javaaddpath('access-path-to-ojdbc8.jar') ;
props = javaObject('java.util.Properties') ;
props.setProperty("user", 'username') ;
props.setProperty("password", 'password') ;
driver = javaObject('oracle.jdbc.OracleDriver') ;
url = 'jdbc:oracle:thin:@ip:port:schema' ;
con = driver.connect(url, props) ;
sql = 'select-query' ;
ps = con.prepareStatement(sql) ;
rs = ps.executeQuery() ;

但是还没有成功地从该ResultSet中检索数据。

如何将Octave中ResultSet对象中的数据放入数组或矩阵中?

EN

回答 2

Stack Overflow用户

发布于 2019-04-20 21:31:32

找出该做什么

您想要用于ResultSet和相关类的文档在Java JDBC API documentation中。(您不需要特定于Oracle的文档,除非您想要做一些特定于Oracle的东西。所有JDBC驱动程序都符合通用JDBC API。)请看一下该教程和任何JDBC教程;因为它是一个Java对象,所以在Octave中使用的方法调用与在Java代码中使用的方法调用是相同的。

对于转换为倍频程的值,要知道Java原语会自动转换为倍频程类型,java.lang.String对象需要通过调用char(...)进行转换,而java.sql.Date值则必须手动转换为datenums。(懒惰的方法是获取它们的字符串值并对其进行解析;快速的方法是获取它们的Unix时间值并进行数值转换。)

做什么?

因为Java JDBC使结果集游标一次前进一行,并且需要单独的方法调用来获取每一列的值,所以您需要使用一对嵌套循环来迭代ResultSet。如下所示:

代码语言:javascript
复制
rsMeta = rs.getMetaData();
nCols = rsMeta.getColumnCount();
data = NaN(1, nCols);
iRow = 0;
while rs.next()
  iRow = iRow + 1;
  for iCol = 1:nCols
    data(iRow,iCol) = rs.getDouble(iCol);
  endfor
endwhile

啊,但是如果你的列不全是数字呢?然后,您需要查看rsMeta中的列类型,打开它,并使用一个单元格数组来保存异构数据集。如下所示:

代码语言:javascript
复制
rsMeta = rs.getMetaData();
nCols = rsMeta.getColumnCount();
data = cell(1, nCols);
iRow = 0;
while rs.next()
  iRow = iRow + 1;
  for iCol = 1:nCols
    colTypeId = rsMeta.getColumnType(iCol);
    switch colTypeId
      case NUMERIC_TYPE
        data{iRow,iCol} = rs.getDouble(iCol);
      case CHAR_TYPE
        data{iRow,iCol} = rs.getString(iCol);
        data{iRow,iCol} = char(data{iRow,iCol});
      # ... and so on ...
      otherwise
        error('Unsupported SQL data type in column %d: %d', ...
          iCol, colTypeId);
    endswitch
  endfor
endwhile

您如何知道NUMERIC_TYPECHAR_TYPE等的值应该是什么?您必须检查java.sql.Types Java类中的值。在运行时执行此操作,以确保与正在运行的JDK保持一致。

(注意:这段代码是一种简单、草率的方式。您可以(也应该)对其进行各种改进和优化。)

如何快速前进

不幸的是,这样做的性能会很糟糕,因为从Octave调用Java方法的开销很大,而且单元格保存数据的效率也很低。如果您的结果集很大,为了获得良好的性能,您需要用Java编写一个结果集缓冲层,它在Java中运行循环,并在每个列的原始数组中缓冲结果,并使用该缓冲层。如果你想要一个如何做到这一点的例子,我有an example implementation in Matlab in my Janklab library (M-代码层here)。请随意窃取代码。Octave不支持Java构造函数或类方法的点引用,因此要将其转换为Octave,需要将所有这些都替换为javaObjectjavaMethod调用。(这很乏味,而且会导致丑陋的代码,所以我不打算自己去做。对不起。)

如果您不愿意这样做(说真的,谁愿意呢?),并且仍然需要良好的性能,那么您实际上应该做的是忘记将Octave直接连接到Oracle,而是编写一个单独的Python/NumPy或R程序,该程序接受您的查询,在Oracle数据库上运行它,并将结果写入一个.mat文件,然后您将从Octave读取该文件。

票数 1
EN

Stack Overflow用户

发布于 2019-04-02 20:22:53

我无法访问指定的.jar或合适的数据库来测试您的特定代码,但无论如何,这都不是一个八度的问题。实际上,您需要用于ResultSet类的相关api,以及处理它的标准方法。oracle documentation建议您在java中执行以下操作:

代码语言:javascript
复制
while (rs.next()) { System.out.println (rs.getString(1)); }

因此,除了通过octave的java接口之外,这大概也是您在octave中要做的事情。一种可能的方式是

代码语言:javascript
复制
while rs.next().booleanValue  % since a Boolean java object by itself
                              % isn't valid logical input for octave's
                              % 'while' statement
    % do something with rs, e.g. fill in a cell array
endwhile

至于你是否可以自动将一个java数组转换成一个octave cell-object,或者反之亦然,据我所知这是不可能的。您必须通过for循环将元素从一个设置/获取到另一个,就像在java中所做的那样(例如,请参阅手册中关于javaArray函数的说明)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55451683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档