runstoredprocedure有个小bug

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., ©zhiqiang, 2011.05.9。请参考右边的相关文章列表。


  • 评论由多说提供支持。该系统支持使用微薄、人人网和QQ的账户登陆,由各自网站直接认证,不会泄露你的密码。
  • 登陆后可选择分享评论到所绑定的社交网络,如微薄、人人和QQ空间。
  • 评论无法修改。如需修改,请删除原评论重新提交。
  • 评论支持LaTeX代码,行内公式请用\(a+b=c\),行间公式请用\[a+b=c\]。公式只支持英文字符。
Loading...
Loading...
Loading...