Spring StoredProcedure中的当前Sql日期原因ORA-01847:每月的日期必须介于1和月的最后一天之间

时间:2014-04-01 15:00:57

标签: java sql oracle stored-procedures

我在Java / Spring中编译当前系统日期如下:

Calendar calobj = Calendar.getInstance();
java.sql.Date currentSysDate = new java.sql.Date(calobj.getTime().getTime());

检查此日期时,它具有以下格式:

2014-04-01

我将此值传递给StoredProcedure中扩展的execute()Map方法(通过 Oracle PL进行更新/ SQL):

public Object execute(java.sql.Date currentSysDate) {

    Map<String, Object> params = new HashMap<String, Object>();
    params.put("current_date", currentSysDate);

    return execute(params);
}

PL / SQL:

{call update_curr_date (
current_date => :current_date
)}

PROCEDURE update_curr_date(current_date  IN DATE) AS
BEGIN

       INSERT INTO plogger (plogger_id, use_case_name, wrapper_name, logged_updates) 
       VALUES (plogger_id_seq.nextval,
           'Date use case',
           'UPDATE_CURR_DATE',
           'current_date = "' || current_date || '"');

END update_curr_date;

这导致在我的单元测试期间抛出以下异常:

ORA-01847: day of month must be between 1 and last day of month
ORA-06512: at line 4
; nested exception is java.sql.SQLDataException: ORA-01847: day of month must be between 1 and last day of month
ORA-06512: at line 4

2 个答案:

答案 0 :(得分:0)

你能完全发布你的代码吗? Alex Poole问你是否使用正确的绑定类型?这个例子对您有用:

create or replace PROCEDURE update_curr_date(current_date  IN DATE)
is
begin
       insert into t values(current_date);
end;
/

class SP extends StoredProcedure{ 
        private static final String SPROC_NAME = "update_curr_date"; 
        public SP( DataSource datasource ){ 
               super( datasource, SPROC_NAME ); 
               declareParameter( new SqlParameter( "current_date", OracleTypes.DATE ) ); 
               compile(); 
        } 
        public Object execute(java.sql.Date p) { 
               Map<String,Object> results = super.execute(p); 
               return null;
        }
} 

...
    public void updateDate() {
        Calendar calobj = Calendar.getInstance();
        java.sql.Date currentSysDate = new java.sql.Date(calobj.getTime().getTime());        
        SP psp = new SP(jdbcTemplate.getDataSource());
        psp.execute(currentSysDate);
    }
...

检查您的参数使用DATE类型绑定。

答案 1 :(得分:0)

我使用的原始存储过程有多个必需参数,包括current_date。我收到相同的异常,这促使我减少所有参数,只使用DATE参数无效。

最后,我放弃了所有参数,并将所有参数放回PL / SQL存储过程和StoredProcedure类中声明的参数。问题是什么,我无法理解为什么,是声明参数的 order ,即:

PROCEDURE update_curr_date(
  h_id    IN NUMBER,
  h_type   IN VARCHAR2,
  h_pnum IN VARCHAR2,
  h_curr_date    IN DATE,
  mode         IN VARCHAR2 DEFAULT 'INSERT');

并在StoredProcedure声明了它:

    declareParameter(new SqlParameter("h_id", OracleTypes.NUMBER));
    declareParameter(new SqlParameter("h_curr_date", OracleTypes.DATE));
    declareParameter(new SqlParameter("h_type", OracleTypes.VARCHAR));
    declareParameter(new SqlParameter("h_pnum", OracleTypes.VARCHAR));

查询字符串:

{call update_curr_date (
h_id => :h_id,
h_type => :h_type,
h_curr_date => :h_curr_date,
h_pnum => :h_pnum

注意mode动态地附加到SQL查询字符串的末尾以及它的相应声明,因为它是一个可选参数,但这不是重点。

当我将h_curr_date的声明移到declareParameter()的末尾时,它有效:

    declareParameter(new SqlParameter("h_id", OracleTypes.NUMBER));
    declareParameter(new SqlParameter("h_type", OracleTypes.VARCHAR));
    declareParameter(new SqlParameter("h_pnum", OracleTypes.VARCHAR));
    declareParameter(new SqlParameter("h_curr_date", OracleTypes.DATE));

鉴于我使用命名参数来执行我的声明并绑定变量,奇怪的是 Spring (或者可能是JDBC的Oracle实现,但我怀疑前者是因为映射是在当参数被无序声明时, Spring 代码)在这种情况下不起作用(我的OUT参数也有一些奇怪的结果)。