如何在 Oracle PL SQL 中减去日期

use*_*025 0 plsql date

我正在使用 Oracle 18c。我试图确定经过的时间,但在 PL SQL 中减去两个日期变量时出现错误。下面的代码工作正常:

DECLARE
    l_zero_date     date;
    l_current_date  date;
    l_elapsed_time  date;
BEGIN
    Execute Immediate 'ALTER SESSION set nls_timestamp_format = "DD-MM-YYYY HH24:MI:SS"';
    l_zero_date := to_date('01-01-1900 00:00:00', 'DD-MM-YYYY HH24:MI:SS');
    dbms_output.put_line('The value of l_zero_date is: ' || l_zero_date);
    Select ls.duration Into l_current_date From LIT_STATS ls Where ls.prim_key = 1002;
    dbms_output.put_line('The value of l_curr_date is: ' || l_current_date);
--    dbms_output.put_line('The elapsed time is: ' || l_current_date - l_zero_date);

END;
Run Code Online (Sandbox Code Playgroud)

这会产生结果:

The value of l_zero_date is: 1900-01-01 00:00:00
The value of l_curr_date is: 1900-01-01 00:35:22
Run Code Online (Sandbox Code Playgroud)

但是,如果我取消注释最后 dbms_output 行,则会收到错误:

Error report -
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at line 14
06502. 00000 -  "PL/SQL: numeric or value error%s"
*Cause:    An arithmetic, numeric, string, conversion, or constraint error
           occurred. For example, this error occurs if an attempt is made to
           assign the value NULL to a variable declared NOT NULL, or if an
           attempt is made to assign an integer larger than 99 to a variable
           declared NUMBER(2).
*Action:   Change the data, how it is manipulated, or how it is declared so
           that values do not violate constraints.
Run Code Online (Sandbox Code Playgroud)

我不明白为什么在涉及两个声明为 DATE 的字段时出现减法错误。例如,以下代码可以正常工作:

declare
        a       date;
        b       date;
begin
        a := sysdate;
        dbms_lock.sleep(10);    -- sleep about 10 seconds give or take
        b := sysdate;
        dbms_output.put_line( b-a || ' of a day has elapsed' );
        dbms_output.put_line( (b-a)*24 || ' of an hour has elapsed' );
        dbms_output.put_line( (b-a)*24*60 || ' of a minute has elapsed' );
        dbms_output.put_line( (b-a)*24*60*60 || ' seconds has elapsed' );
end;
Run Code Online (Sandbox Code Playgroud)

为什么该行会dbms_output.put_line('The elapsed time is: ' || l_current_date - l_zero_date);产生错误?
感谢您查看此内容。

小智 5

正如我在评论中提到的,这是一个操作顺序问题。举个例子:

SELECT 'TEST'||SYSDATE-SYSDATE FROM DUAL
Run Code Online (Sandbox Code Playgroud)

当它运行时,我收到以下错误:ORA-00932: inconsistent datatypes: expected CHAR got DATE

但是当我将日期包含在(and中时)

SELECT 'TEST'||(SYSDATE-SYSDATE) FROM DUAL
Run Code Online (Sandbox Code Playgroud)

结果是TEST0

这是运算顺序,代码从左向右移动,除非有括号通知它首先进行日期减法。

这是一个 DBFiddle,显示正在运行的查询(链接