转换 Oracle 存储过程 DATE 输入参数

Converting an Oracle Stored Procedure DATE Input Parameter

我是 Oracle 的新手,对存储过程的输入参数有疑问。基本上它是一个从外部系统调用的存储过程,传递格式为 MM/DD/YYYY.

的日期

Oracle 似乎不喜欢 MM/DD/YYYY 格式,因为它给我一个 "not a valid month" 错误。 (我认为它想要一个 DD-MMM-YYYY?)无论默认值是什么。

有没有一种方法可以在不出错的情况下转换进入过程的日期?

如:

    create procedure test_proc
(
 v_input_date IN DATE := to_char(v_input_date, 'MM/DD/YYYY')
)

我知道上面的代码可能没有任何实际意义,但希望它能传达我想做的事情。用户会调用类似

的过程
BEGIN
test_proc('01/01/2018')
END

您可以尝试使用 ANSI 类型 date 'yyyy-mm-dd' 格式,如下例所示:

SQL>create or replace procedure test_proc( v_input_date date ) is
  v_diff int;
begin
  v_diff := trunc(sysdate)-v_input_date;
  dbms_output.put_line(v_diff||' days difference...');
end;
/

SQL> set serveroutput on;
SQL> begin
  test_proc(date '2018-03-21');
end;
/
2 days difference...

您的问题不在过程中,而是在调用过程的代码中。

'01/01/2018' 不是日期,它是一个字符串,但您的程序需要一个日期;但是,Oracle 试图提供帮助,并会隐式尝试使用 TO_DATE( string_value, format_model ) 函数将字符串转换为日期。由于它没有指定的格式模型,它将使用日期的默认格式,即 ,如果此格式掩码与字符串的格式不匹配,则会出现错误。

(注意:会话参数是 per-user-session 并且可以由每个用户更改,因此您不应该依赖它们对每个用户都相同,甚至在会话之间相同用户!)

您可以使用查询查看 NLS_DATE_FORMAT 会话参数的格式:

SELECT VALUE
FROM   NLS_SESSION_PARAMETERS
WHERE  PARAMETER = 'NLS_DATE_FORMAT';

并且您调用该过程的代码被隐式转换为如下内容:

BEGIN
  test_proc(
    TO_DATE(
      '01/01/2018',
      ( SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT' )
    )
  );
END;

要生成日期,您应该通过以下方式将字符串显式转换为日期: