runstoredprocedure 有个小 bug

作者: , 共 1696 字

Matlab 内置的 runstoredprocedure 函数,用来运行同时有输入和输出参数的存储过程:

x = runstoredprocedure(c, 'myproc', {2500, 'Jones'}, {java.sql.Types.NUMERIC})

同事在用的时候发现一个 bug ,但在网上居然找不到相关的信息。该 bug 出现在访问非 SQL 的数据库的储存过程时,至少存在于 R2010b 版。问题出现在对字符串输入参数的处理上( line 50 - 57 ):

%Build stored procedure call
spcall = [spcall '('];
for i = 1:length(inarg)
  if isnumeric(inarg{i}) || islogical(inarg{i})
    inarg{i} = num2str(inarg{i},17);
  elseif strcmp(sDbName,'MySQL') || strcmp(sDbName,'Microsoft SQL Server')
    inarg{i} = ['''' inarg{i} ''''];
  end
  spcall = [spcall inarg{i} ','];    %#ok, not sure how long spcall will be
end

上面这段代码是将储存过程的输入参数转化为函数参数的形式

myproc(2500, 'Jones',

但对于 Oracle 数据库或者其它非 SQL 类型的数据库,它被转化为了

myproc(2500, Jones,

上面的 Jones 左右边没有引号,当传入数据库进行执行时,数据库识别不出 Jones 是什么含义,从而导致报错:

??? Java exception occurred:
java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'myproc'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source)

at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)

at sun.jdbc.odbc.JdbcOdbc.SQLExecute(Unknown Source)

at sun.jdbc.odbc.JdbcOdbcPreparedStatement.execute(Unknown Source)

at sun.jdbc.odbc.JdbcOdbcPreparedStatement.executeUpdate(Unknown Source)

修改方法很简单,在 runstoredprocedure 的第 53 行的 elseif 中间加一个%号,即

elseif strcmp(sDbName,'MySQL') || strcmp(sDbName,'Microsoft SQL Server')

改成

else%if strcmp(sDbName,'MySQL') || strcmp(sDbName,'Microsoft SQL Server')

也可以下载修改后版本,直接覆盖 Matlab 安装目录下的 \toolbox\database\database\@database\ 目录下的 runstoredprocedure.m。

Q. E. D.

类似文章:
Matlab 的 database 工具箱只支持 ODBC 数据库连接,在使用之前需要先设置 ODBC 数据源。之前在 Excel 里用的是 ADODB ,使用 ADODB 的好处是无需设置 ODBC 源,似乎效率也要高一些(但我一直没弄懂 ADODB 是什么东西,所以效率这东西我也说不清)。
Excel、Matlab 在与数据库交互数据时,通常需要事先配置好 ODBC 数据源,这导致一个文件换到另一台机器还需要重新配置 ODBC。手工配置太麻烦,从国外一个网站看到一种解决方案:
更新一下之前写的Excel 的数据库类,将其改成函数的形式,调用更简单(省却了生成类实例的步骤)。现在这个代码在工作中用了一年多,已经比较健壮。若有问题,请留言指出或与我联系。
2014-03-25 更新:我已经将该类修改成函数形式,并增加新功能,参见更新 Excel 的数据库查询函数库
编程 » Java, Matlab
Matlab 2008b 才开始引入 containers.Map ,这是 Matlab 唯一的数据结构(这里的数据结构是指自带一定逻辑性的数据结构,不包括普通数据类型)。如果要有其它,比如 Queue、Set 等数据结构,只能自己编写一个。File Exchange 上有不少人做过这个工作,我也写过Queue、List、Vector 的 Matlab 对象。不过 Matlad 的面向对象编程效率极低,这种方法只能用于不太注重效率的场合。解决这个问题的另外一个方法是使用 Java 对象。
相似度: 0.071
编程 » Matlab
写了一个统计代码量的函数,函数已上传到 Matlab Central File Exchange下载地址,使用方法:
最近用 Matlab 写了个东西,运行效率不如我意。用 Profiler 跟踪了一下,结果让我大吃一惊。其中三分之一的时间花费在 datestr 这个函数上,六分之一的时间花费在 save 和 load 数据上。这里先谈前一个问题,关于 save 和 load 的效率以后再谈。
编程 » SQL
现在 Access 用的人应该不多了,本来我以为我也不可能用这玩意儿,但最近在用 VBA 通过 SQL 处理数据时,发现它的语法是 Access 的语法。平时对 SQL Server 语法相对熟悉一些。下文总结了 Access 和 SQL Server 语法的差异。
如果一个日期(或者时间),如果用字符串,比如"2010-10-04"的形式,各个系统都没有什么区别。在某些时候,将日期用数字表示,将大大增加对日期查找、比较的效率。而如果用数字来表示日期,在不同的系统之间差别就大了。
Excel 多表合并和查询是一个应用很广泛的问题。下面是一个简单的例子,我们需要从两张数据表里,得出每个行业的股票波动率平均值。第一个数据表保存了股票和行业的对应关系,有两列,第一列为股票名,第二列为每只股票对应的行业。第二张表保存了各个股票在各个交易日的收盘价和前收盘价,有四列,第一列是股票名,第二列为交易日,第三列和第四列分别为股票在这个交易日的前收盘价和收盘价。
风险管理 » VaR, VaR Primer
不管受到多少质疑,各大商业银行和投资银行的财务报表显示, VaR 框架已是现代风险管理的事实标准。我打算用接下来三个月的时间,对 VaR 框架进行一个全面的介绍,从历史到未来、从原理到算法、从逻辑框架到技术细节。这是酝酿了将近一个月的文章,原本打算写一个长篇文章,但随着资料的积累,也有了一些雄心,打算将这个领域彻底梳理一篇,到最后将完成若干篇文章,所有文章都将位于VaR Primer系列下。
今天一个朋友向我提起他参与北京买车摇号,他自己和周围十来人都没有摇中的事情,我关注了一下摇号的一些数据。