在 Oracle 中,我必须签入哪个数据库参数才能在函数中签入默认 DATE 参数?



我有以下奇怪的问题。我有一个包中的以下过程:

PROCEDURE createSmth (p_param1        IN     VARCHAR2,
p_param2        IN     NUMBER,
p_param3        IN     DATE,
p_param4        IN     DATE,
p_description   IN     VARCHAR2,
p_last_login    IN     VARCHAR2 DEFAULT NULL,
o_sid           OUT    NUMBER,
p_ret           OUT    NUMBER,
p_mess          OUT    VARCHAR2);

调用此过程的应用程序正在使用"oracledb":"^4.2.0"。 以下是开发日志(格式化以便于阅读(:

DBService: calling stored procedure 'BEGIN pkg.createSmth(
:p_param1, 
:p_param2, 
:p_param3, 
:p_param4, 
:p_description, 
:p_last_login, 
:o_sid, 
:p_ret, 
:p_mess); END;' 
with bindings 
[{"dir":3001,"type":2001,"val":"test"},
{"dir":3001,"type":2010,"val":37},
{"dir":3001,"type":2001,"val":"01/06/2020"},
{"dir":3001,"type":2001,"val":"03/06/2020"},
{"dir":3001,"type":2001,"val":"test233"},
{"dir":3001,"type":2001,"val":"admin"},
{"dir":3003,"type":2010},
{"dir":3003,"type":2010},
{"dir":3003,"type":2001}]
pkg.createSmth: get connection - 1 ms
pkg.createSmth: execute statement - 225 ms
pkg.createSmth: get values - 225 ms

在生产中发生以下情况(格式化以便于阅读(:

DBService: calling stored procedure 'BEGIN pkg.createSmth(
:p_param1, 
:p_param2, 
:p_param3, 
:p_param4, 
:p_description, 
:p_last_login, 
:o_sid, 
:p_ret, 
:p_mess); END;' 
with bindings 
[{"dir":3001,"type":2001,"val":"test"},
{"dir":3001,"type":2010,"val":37},
{"dir":3001,"type":2001,"val":"01/06/2020"},
{"dir":3001,"type":2001,"val":"03/06/2020"},
{"dir":3001,"type":2001,"val":"test233"},
{"dir":3001,"type":2001,"val":"admin"},
{"dir":3003,"type":2010},
{"dir":3003,"type":2010},
{"dir":3003,"type":2001}]
pkg.createSmth: get connection - 0 ms
Unexpected DB error
undefined: Error: ORA-01843: not a valid month
ORA-06512: at line 1, trace: Error: ORA-01843: not a valid month
ORA-06512: at line 1

在 dev 和 prod 上,IN 参数的 oracledb 类型都设置为 STRING。

执行select sysdate from dual会在两个数据库上返回相同的日期格式:16-JUN-20

因此,任何解决此问题的提示将不胜感激。

如果过程需要DATE,请不要提供STRING。

这是字符串:

'01/06/2020'

这些是日期:

date '2020-06-01'
to_date('01/06/2020', 'dd/mm/yyyy')

选择一个最适合您的选项;如果您总是传递日期(没有时间部分(,则日期文本(始终采用格式date 'yyyy-mm-dd'(就可以了。如果您要打发时间,那么to_date(使用适当格式的掩码(可能是更好的选择。

此错误可能有多种原因。例如,它可以是NLS_DATE_FORMAT参数或TO_DATE函数中的格式参数。

您需要分析代码来解决此问题。

例:

SQL> show parameter nls_date_format
NAME                     TYPE    VALUE
------------------------------------ ----------- ------------------------------
nls_date_format              string  DD/MM/YYYY
SQL> select to_date('06/16/2020') from dual;
select to_date('06/16/2020') from dual
*
ERROR at line 1:
ORA-01843: not a valid month

SQL> select to_date('16/06/2020') from dual;
TO_DATE('1
----------
16/06/2020
SQL> 

而不是01/06/2020使用

  • to_date('01/06/2020','dd/mm/yyyy')

  • date '2020-06-01'-- 日期文字

要了解会话/数据库使用的日期格式,您可以使用NLS_SESSION_PARAMETERSNLS_DATABASE_PARAMETERS视图(参数名称:NLS_DATE_FORMAT(。但建议将特定格式与to_datedate literal一起使用NLS_DATE_FORMAT因为可能会随着时间的推移而变化,并且您的代码将不起作用。

最新更新