我需要将包含日期的字符串转换为日期数据类型字段。有时,字符串的格式为yyyy-mm-dd hh24:mi:ss (FA),有时的格式为dd/mm/yyyy hh24:mi:ss (FB)。我正在使用一小段代码来测试、拦截和管理 ORA-01861,但我遇到了一个意想不到的问题。我试着解释一下。
declare
s varchar2(100) := '2023-02-24 14:22:49';
f varchar2(100) := null;
f1 varchar2(100) := 'yyyy-mm-dd hh24:mi:ss';
f2 varchar2(100) := 'dd/mm/yyyy hh24:mi:ss';
d date := null;
begin
f := f1;
d := to_date(s,f);
dbms_output.put_line(f||' --> '||d);
f := f2;
d := to_date(s,f);
dbms_output.put_line(f||' --> '||d);
exception
when others then
dbms_output.put_line(s||' --> '||f||' >>>> '||sqlerrm);
end;
Run Code Online (Sandbox Code Playgroud)
我期望的是,更改S的格式会由于格式不匹配而引发异常,在第一个示例中,这就是发生的情况。输出是:
yyyy-mm-dd hh24:mi:ss --> 24-FEB-23
2023-02-24 14:22:49 --> dd/mm/yyyy hh24:mi:ss >>>> ORA-01861: literal does not match format string
Run Code Online (Sandbox Code Playgroud)
但如果我像这样更改值:
declare
s varchar2(100) := '05/03/2023 08:44';
f varchar2(100) := null;
f1 varchar2(100) := 'yyyy-mm-dd hh24:mi:ss';
f2 varchar2(100) := 'dd/mm/yyyy hh24:mi:ss';
d date := null;
begin
f := f1;
d := to_date(s,f);
dbms_output.put_line(f||' --> '||d);
f := f2;
d := to_date(s,f);
dbms_output.put_line(f||' --> '||d);
exception
when others then
dbms_output.put_line(s||' --> '||f||' >>>> '||sqlerrm);
end;
Run Code Online (Sandbox Code Playgroud)
没有任何异常,输出是:
yyyy-mm-dd hh24:mi:ss --> 20-MAR-05
dd/mm/yyyy hh24:mi:ss --> 05-MAR-23
Run Code Online (Sandbox Code Playgroud)
我对解决方案、解决方法等感到好奇。
当你这样做时:
TO_DATE('05/03/2023 08:44', 'yyyy-mm-dd hh24:mi:ss')
Run Code Online (Sandbox Code Playgroud)
那么生成的日期就是0005-03-20 23:08:44。
这是因为:
yyyy比赛05(公元 5 年)-也匹配/(正如字符串到日期转换规则所述“您可以在日期字符串中使用任何非字母数字字符来匹配格式字符串中的标点符号。”)mm火柴03-也匹配/dd火柴20hh24火柴23:也会被忽略mi火柴08; 和:已匹配ss火柴44。如果您想引发异常,请使用与fx格式模型的完全匹配:
TO_DATE('05/03/2023 08:44', 'fxyyyy-mm-dd hh24:mi:ss')
Run Code Online (Sandbox Code Playgroud)
你会得到异常:
ORA-01862: the numeric value does not match the length of the format item
Run Code Online (Sandbox Code Playgroud)