【问题标题】:How to compare dates in a PL/SQL procedure?如何比较 PL/SQL 过程中的日期?
【发布时间】:2025-12-29 21:15:11
【问题描述】:

我是 SQL 编程的新手。

我需要制定一个程序来比较日期。该过程中的唯一参数是用户在 Java 程序中输入的日期。我需要检查该参数(日期)是否在一年前。换句话说,我需要将它与 SYSDATE 减去一年进行比较。如果是这种情况,我必须“清除”所有与“时间表”相关的表(其中有 2 个)。

例如,假设用户键入 2013-04-13,我的程序必须将其与 SYSDATE - 1 年进行比较(在这种情况下,它将是 2014-12-03)。由于该值小于今天减去一年,因此必须清除表“MovieSchedule”和“ChannelSchedule”。如果输入的日期是 2014 年 12 月 16 日,因为它现在比 SYSDATE 减去一年多,该过程必须发回一个明确的错误,我将能够在 Java 程序中使用该错误。

现在,正如我所说,我对 PL/SQL 中的过程编程完全陌生,所以通过在 Internet 上查找教程可以得出以下结论:

CREATE OR REPLACE
PROCEDURE purge_schedule(purgeDate date) AS

DECLARE
currentDate := to_date(SYSDATE, 'YYYMMDD');

BEGIN

    -- IF purgeDate < (currentDate - 1year)
        -- delete content in "MovieSchedule" and "ChannelSchedule"
    -- ELSE
        -- return explicit error

END purge_schedule;

我什至不知道这是否是编写我想要的程序的正确方法。正如你所看到的,我的问题是如何在程序中实现我的条件,而不是它背后的逻辑。我责怪我缺乏对语言的练​​习。

如果您需要更多信息以帮助我,请告诉我是否需要更具体。感谢您的帮助,祝您有愉快的一天:)

【问题讨论】:

  • to_date(SYSDATE, 'YYYMMDD') 毫无意义。它将sysdate(即DATE)转换为varchar,然后将varchar转换回原来的date

标签: oracle date stored-procedures plsql


【解决方案1】:
I have illustrated a below working code which help you. Let me know if this helps.

--Compiling the stored proc
CREATE OR REPLACE PROCEDURE purge_schedule(
    purgeDate IN DATE )
AS
  currentDate DATE:=SYSDATE;
BEGIN
  IF purgeDate < ADD_MONTHS(SYSDATE,-12) THEN
    DELETE FROM EMP;
    DELETE FROM EMP_V1;
    dbms_output.put_line('Records purged successfully');
  ELSE
    RAISE_APPLICATION_ERROR(-20001,'Date provided is not in range deletion not invoked',TRUE);
  END IF;
END purge_schedule;

-- Exceuting the proc
set serveroutput on;
exec purge_schedule(to_date('12/12/2013','MM/DD/YYYY'));

--  Output
Records purged successfully

--Executing for negative scenario
set serveroutput on;
exec purge_schedule(TO_DATE('12/12/2017','MM/DD/YYYY'));

--Explicit exception raise

exec purge_schedule(TO_DATE('12/12/2017','MM/DD/YYYY'));
Error report -
ORA-20001: Date provided is not in range deletion not invoked
ORA-06512: at "AVROY.PURGE_SCHEDULE", line 11
ORA-06512: at line 1

【讨论】:

  • date 值上调用to_date()date 转换为date 是无用且错误的。它将date 值转换为varchar,然后将varchar 转换回原来的date
  • 哦,所以我们可以只传递简单的日期字符串,而不是用 to_date() 解析它?
  • purgeDate 定义为DATE。无需将其“解析”为日期。
  • 那是错误的编辑。 TO_DATE(purgeDate,'MM/DD/YYYY') 无用且错误。 调用过程时传递正确的date文字是绝对正确的
【解决方案2】:

第 1 步,定义年份。应该很明显,但不是。我发现月份和年份的定义在野外是不同的。我见过定义为 52 周的年份,这从来都不是实际的年份,以及 365 天,与一年相匹配的时间略少于每 4 年中的 3 天,有时是 360 天! (30天/月*12个月)

sysdate - 365 给出 365 天前的日期。

ADD_MONTHS(sysdate, -12) 将给出 12 个月前的日期。如果sysdate 是 2 月 29 日,则结果将为上一年的 2 月 28 日。

sysdate - interval '1' year 很诱人,但是当“结果”是不存在的那一天时,interval year to month 算术会抛出错误。

select date '2012-02-28' - interval '1' year from dual;

2011 年 2 月 28 日

select date '2012-02-29' - interval '1' year from dual;

ORA-01839: 指定月份的日期无效

【讨论】:

    【解决方案3】:

    它应该满足您的需求:

    IF purgeDate < SYSDATE -365 THEN
        ...
    END IF;
    

    【讨论】: