首页 > 解决方案 > 如何形成 oracle 函数 - 如果 /else 返回不同的 TIMESTAMP 值

问题描述

我正在尝试创建一个 sql 函数,如果满足某个条件,则返回一个 TIMESTAMP 值,否则返回一个 TIMESTAMP 值加上额外的 30 天。这是我创建的函数(但未编译):

CREATE OR REPLACE FUNCTION "DUEDATE" (DATE_A IN TIMESTAMP, NUM_DAYS IN NUMBER, DATE_B IN TIMESTAMP) 
RETURN TIMESTAMP AS 
BEGIN
  IF SYSDATE - CAST(DATE_B) < 30
    RETURN CAST(DATE_A AS DATE) + (((NUM_DAYS/30) + 1)) * 30
  ELSE
    RETURN CAST(DATE_A AS DATE) + ((((NUM_DAYS/30) + 1)) * 30) + 30
END;

非常感谢任何帮助。谢谢!

标签: oraclesql-function

解决方案


您的计算似乎等于将 30 或 60 天添加到DATE_A,所以我不确定您为什么要进行除法和乘法运算。我也不确定你为什么在参数和返回值是时间戳时使用日期;你可以坚持使用时间戳和间隔:

CREATE OR REPLACE FUNCTION "DUEDATE" (DATE_A IN TIMESTAMP, NUM_DAYS IN NUMBER, DATE_B IN TIMESTAMP) 
RETURN TIMESTAMP AS 
BEGIN
  IF DATE_B > SYSTIMESTAMP - INTERVAL '30' DAY THEN
    RETURN DATE_A + (NUM_DAYS + 30) * INTERVAL '1' DAY;
  ELSE
    RETURN DATE_A + (NUM_DAYS + 60) * INTERVAL '1' DAY;
  END IF;
END;
/

或者

CREATE OR REPLACE FUNCTION "DUEDATE" (DATE_A IN TIMESTAMP, NUM_DAYS IN NUMBER, DATE_B IN TIMESTAMP) 
RETURN TIMESTAMP AS 
BEGIN
  RETURN DATE_A + (NUM_DAYS + CASE WHEN DATE_B > SYSTIMESTAMP - INTERVAL '30' DAY
                                   THEN 30 ELSE 60 END) * INTERVAL '1' DAY;
END;
/

据我所知,得到相同的结果 - 除了它会保留小数秒,当你投射到日期时会丢失。


db<>fiddle 演示今年每天都运行这两个函数,并且还显示了 @OldProgrammer 版本的结果,有和没有CAST(DATE_B AS DATE)- 注意 (a) 前两个函数保留小数秒,和 (b) 第三个变得不同结果直到您到达 30 天前(今天运行,结果第 18 页上的 2018-06-26 更改)。


推荐阅读