Java Spring StoredProcess中的当前Sql日期导致ORA-01847:月日必须介于1和月的最后一天之间
我正在Java/Spring中编译当前系统日期,如下所示:Java Spring StoredProcess中的当前Sql日期导致ORA-01847:月日必须介于1和月的最后一天之间,java,sql,oracle,stored-procedures,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 我正在将此值传递给扩展的storedProcess类的execute()方法,该方法位于Map(通过Oracle PL/SQL更新): 这导致在我
Calendar calobj = Calendar.getInstance();
java.sql.Date currentSysDate = new java.sql.Date(calobj.getTime().getTime());
检查此日期时,其格式如下:
2014-04-01
我正在将此值传递给扩展的storedProcess
类的execute()
方法,该方法位于Map
(通过Oracle PL/SQL更新):
这导致在我的单元测试期间引发以下异常:
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
你能完整地发布你的代码吗?您是否按照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);
}
...
创建或替换过程更新当前日期(日期中的当前日期)
是
开始
插入t值(当前日期);
结束;
/
类SP扩展了StoredProcedure{
私有静态最终字符串存储过程\u NAME=“更新当前日期”;
公共SP(数据源数据源){
超级(数据源、存储过程名称);
declareParameter(新的SqlParameter(“当前_日期”,OracleTypes.date));
编译();
}
公共对象执行(java.sql.datep){
Map results=super.execute(p);
返回null;
}
}
...
公共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(当前系统日期);
}
...
检查您的参数使用的日期类型绑定。我使用的原始存储过程有多个必需的参数,包括
当前\u日期
。我收到了同样的异常,提示我减少所有参数,只使用日期
参数无效
最后,我放弃并将所有参数放回PL/SQL存储过程中,并在StoredProcedure
类中声明参数。问题是,我不明白为什么,参数的声明顺序,即:
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');
并在存储过程中声明:
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
注意:模式
被动态地附加到SQL查询字符串的末尾及其相应的声明,因为它是一个可选参数,但这并不重要
当我将h\u curr\u 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
参数方面遇到了一些奇怪的结果)。@HamletHakobyan添加了Spring和PL/SQL接口中使用的查询字符串。我认为这些附加信息并不相关,因为在SQL Developer中运行时,包装器在传递相同的确切日期格式('2014-04-01')时执行得很好@Malvon-这是相关的,因为您的过程期望参数是日期正在传递一个字符串,因此两个会话都在隐式转换为date
;由于一个有效,另一个无效,这两个会话具有不同的NLS\u date\u格式设置。您有一个sql.date
,但它在绑定时似乎被转换为字符串;不过您还没有显示绑定步骤。@AlexPoole你能详细说明一下绑定步骤吗?我不太明白。谢谢。@Malvon-你正在用绑定变量:current_date
执行调用
;你能包括将值(bind)设置为参数值current_date
的代码吗?我假设这是setString()
调用。(除非Spring在幕后为您处理;我不使用另一种技术!)@AlexPoole我明白了。该值直接传递给execute()
,Spring的StoredProcedure
类负责处理细节(CallableStatement
)内部。我的代码与您的代码相同,具有正确的绑定类型OracleTypes.DATE
。即使我传递了null
,我也会得到相同的错误。为什么?甚至new java.sql.Timestamp(System.currentTimeMillis())
也会重复相同的异常。
{call update_curr_date (
h_id => :h_id,
h_type => :h_type,
h_curr_date => :h_curr_date,
h_pnum => :h_pnum
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));