从 java 调用存储过程时出错

Posted

技术标签:

【中文标题】从 java 调用存储过程时出错【英文标题】:Error while invoking a stored procedure from java 【发布时间】:2012-12-27 03:30:31 【问题描述】:

我在postgres 数据库中编写了以下存储过程

create or replace function reviseTax(revisiondate date, taxrate decimal) returns         table(employeeid integer, month date, difference decimal) AS $$
declare
    thisrow record;
    newTaxAmt decimal;
    differenceAmt decimal;
begin 
for thisrow in select * from employee_salary where salarydate >= revisiondate loop
    newTaxAmt = thisrow.income * $2;
    differenceAmt = newTaxAmt - thisrow.tax;
    update employee_salary es set tax = newTaxAmt where es.employeeid = thisrow.employeeid;
    insert into taxrevision (employeeid , month , difference) values (thisrow.employeeid , thisrow.salarydate , differenceAmt);

end loop;
return query select * from taxrevision as something;
end $$ language plpgsql;

当从数据库调用时,这可以正常工作。 问题是当我使用 JDBC 代码从 java 调用这个存储过程时

我的java代码如下

System.out.println("Enter the effective date(yyyy-mm-dd) for the tax revision");
dateString = scanner.next();
float newTaxRate = 0.3F;

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
df.setLenient(false);
java.util.Date utilDate = df.parse(dateString);
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());

CallableStatement callable = DBConnection.prepareCall("call revisetax(?,?)");
callable.setDate(1,sqlDate);
callable.setFloat(2,newTaxRate);
callable.executeQuery();
DBConnection.commit();

我收到以下错误:

ERROR: function revisetax(unknown, real) does not exist
  Hint: No function matches the given name and argument types. You might need to add             explicit type casts.
  Position: 14

我不知道为什么,请帮忙!

【问题讨论】:

你必须使用CallableStatement 亲爱的jeebus,请告诉我这实际上并没有在现实世界中进行财务计算。因为如果它确实让我知道是哪家公司,所以我从不使用它们。对于任何想知道我指的是使用 FLOATS 的人 这不是任何真实世界的计算!我正在尝试原型的简化版本。感谢您的关心! 【参考方案1】:

当您在数据库中调用存储过程/函数时,您希望使用CallableStatement 对象。

CallableStatement callable = new CallableStatement("call my_function(?)");

注意可调用语句中的花括号。

【讨论】:

我已经用 CallableStatement 替换了 PreparedStatement,即使这样还是同样的错误! :( @codeMan 请使用您尝试过的新代码编辑您的原始问题。【参考方案2】:

用这个

 call reviseTax(?,?)

【讨论】:

【参考方案3】:

我明白了!!问题在于存储过程标头中的十进制数据类型

create or replace function reviseTax(revisiondate date, taxrate decimal) returns         table(employeeid integer, month date, difference decimal) AS $$

声明

我使用 real 而不是 decimal,它成功了!!

所以函数头应该是

create or replace function reviseTax(revisiondate date, taxrate real) returns         table(employeeid integer, month date, difference decimal) AS $$

声明

附:而不是 realdouble precision 也可以

【讨论】:

如果你想使用十进制,那么你必须对 CallableStatement 使用 setBigDecimal(String parameterName, BigDecimal x) 方法 哦..你知道!谢谢!!我会尝试一下。

以上是关于从 java 调用存储过程时出错的主要内容,如果未能解决你的问题,请参考以下文章

从存储过程刷新物化视图时出错(不是有效月份)

spring+ibatis 调用Oracle存储过程出错

调用存储过程,提示:从数据类型 nvarchar 转换为 float 时出错。 请问哪里的错?(不好意思没分了)

从另一个存储过程调用 sp_addextendedproperty 时出错

如何从 java 调用 MSSQL 存储过程

使用输出参数调用oracle存储过程时Azure逻辑应用程序出错