转换 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;
要生成日期,您应该通过以下方式将字符串显式转换为日期:
使用 ANSI literal
BEGIN
test_proc( DATE '2018-01-01' );
END;
或 specifying the format mask used in the conversion
BEGIN
test_proc( TO_DATE( '01/01/2018', 'MM/DD/YYYY' ) );
END;
我是 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;
要生成日期,您应该通过以下方式将字符串显式转换为日期:
使用 ANSI literal
BEGIN test_proc( DATE '2018-01-01' ); END;
或 specifying the format mask used in the conversion
BEGIN test_proc( TO_DATE( '01/01/2018', 'MM/DD/YYYY' ) ); END;