ORA-01841:(完整)年份必须介于-4713和+9999之间,并且在使用DBMS_SQL绑定到动态sql时不能为0

时间:2014-04-02 16:12:54

标签: plsql oracle11g dynamic-sql

当我跑步时(这里的片段):

t_cmd := 'begin :1 := other_package.some_function(:0,:1,:2); end;';
l_tmstmp timestamp_unconstrained := to_timestamp('1999-07-07 07:07:07.000000000',
'YYYY-MM-DD HH24:MI:SS.FF9');

DBMS_SQL.PARSE(curid, t_cmd, DBMS_SQL.NATIVE);
-- binding here other attributes
DBMS_SQL.BIND_VARIABLE(curid, ':2',  l_tmstmp);
ret := DBMS_SQL.EXECUTE(curid);

我总是收到错误,即使尝试绑定简单的时间戳,来自varchar2的时间戳(TO_TIMESTAMP('timestamp_in_proper_format'),'YYYY-MM-DD HH24:MI:SS.FF9')):

ORA-01841 :(full) year must be between -4713 and +9999, and not be 0
ORA-06512: przy linia 1
ORA-06512: przy "SYS.DBMS_SQL", line 1825
ORA-06512: przy "MY_PACKAGE", line where is :

ret := DBMS_SQL.EXECUTE(curid);

调试包时不会发生什么有趣的问题。 我试着编译我的包:

 ALTER PACKAGE my_package COMPILE DEBUG PACKAGE;

但问题仍然存在,除了在生产环境中,它将以优化级别编译,所以我不能这样做。 另外我不能使用EXECUTE IMMEDIATE因为函数名称,类型和参数数量在运行时是已知的。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

谢谢@OldProgrammer! 当我试图按照你的建议运行简单的代码段时,我意识到了一些事情。 问题在于这一行:     t_cmd:='begin:1:= other_package.some_function(:0,:1,:2);结束;';

我没有更改此片段的绑定名称:“begin:1”,现在我有两个绑定到相同的值。 在执行立即可以,因为绑定的ORDER很重要,dbms_sql使用绑定的名称。 参数:some_function(:0,:1,:2)中的1也是时间戳。 some_function返回varchar2,因此在尝试将结果替换为第一个“:1”时发生错误。

我将函数调用更改为:

t_cmd := 'begin :my_result := other_package.some_function(:0,:1,:2); end;';

并且“ORA-01841 :(完整)年份必须介于-4713和+9999之间”。

我没有关注这个片段“begin:1:=”因为试图从这样的函数得到结果:

ret := DBMS_SQL.EXECUTE(curid);  
src_cur := DBMS_SQL.TO_REFCURSOR(curid);
FETCH src_cur INTO my_result;  
CLOSE src_cur;

但这样从函数得到的结果不起作用(发生了一些其他错误)

最后我将上面的代码更改为:

ret := DBMS_SQL.EXECUTE(curid);
DBMS_SQL.VARIABLE_VALUE(curid, 'my_result', my_result);  
DBMS_SQL.CLOSE_CURSOR(curid);

现在一切正常。