从Java调用的Oracle存储过程中的日期格式

时间:2015-09-07 17:32:18

标签: java oracle stored-procedures jdbc

我正在尝试使用Oracle存储过程来更新数据库表。我从Java程序调用该过程。我希望我的程序接受格式为'01 -01-2015'的日期,但由于某种原因,我的程序只接受格式为'01 -JAN-2015'的日期。

我的存储过程:

    DELIMITER //
CREATE OR REPLACE PROCEDURE updateAward
(
    p_award_id IN awards.award_id%TYPE,
    p_award_date IN awards.award_date%TYPE,
    p_total_amount IN awards.total_amount%TYPE,
    p_number_sales IN awards.number_sales%TYPE,
    p_emp_id IN awards.emp_id%TYPE
)
AS
BEGIN
UPDATE awards
SET award_date = to_date(p_award_date, 'DD-MM-YYYY'),
total_amount = p_total_amount,
number_sales = p_number_sales,
emp_id = p_emp_id
WHERE award_id = p_award_id;

COMMIT;
END;
/

调用它的java代码:

public boolean updateByID(Connection conn, String strVar, int[] intVar, double doubleVar)
    {
        System.out.println(strVar);
        System.out.println(doubleVar);
        System.out.println(intVar[0]);
        System.out.println(intVar[1]);
        System.out.println(intVar[2]);
        try
        {
            String query = "{call updateAward(?,?,?,?,?)}";
            CallableStatement stmt = conn.prepareCall(query);

                stmt.setInt(1,intVar[0]);
                stmt.setString(2, strVar);
                stmt.setDouble(3, doubleVar);
                stmt.setInt(4, intVar[1]);
                stmt.setInt(5, intVar[2]);

                stmt.executeUpdate();
                return true;
        }
        catch(SQLException e)
        {
            System.out.println(e.getMessage());
        }
        return false;
    }

控制台打印出传递的变量:

12-12-2012
65165.2
21
22
3

错误本身:

KORA-01843: not a valid month
ORA-06512: at line 1

我找到的每个解决方案都是将日期格式放在过程中。我相信我已经用

完成了
award_date = to_date(p_award_date, 'DD-MM-YYYY'),

我写错了吗?有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

目前您正在传递字符串:

stmt.setString(2, strVar);

你正在解析一个字符串:

award_date = to_date(p_award_date, 'DD-MM-YYYY')

您希望自定义类型中包含日期,这就是转换失败的地方。将其更改为VARCHAR(或VARCHAR2),它将起作用。

答案 1 :(得分:1)

您正在通过setString()将字符串传递给期望Oracle日期参数的过程。这意味着在您到达to_date()电话之前,Oracle必须使用会话/区域设置NLS_DATE_FORMAT将字符串隐式转换为日期作为通话的一部分。

您可以将过程参数类型从awards.award_date%TYPE更改为varchar2,并且仍然可以在过程中进行显式转换。或者您可以保留过程签名,并通过在Java端转换它来传递正确的数据类型,例如:

SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
cStmt.setDate(2, new java.sql.Date(sdf.parse(strVar).getTime()));

由于p_date已经是日期,因此您不应该在其上调用to_date(),因为它会将隐式转换回字符串(再次使用NLS_DATE_FORMAT),然后尝试显式转换使用您提供的格式模型返回日期,这也可能会产生类似的错误。简化为:

SET award_date = p_award_date,