【问题标题】:Create calendar function in Oracle using WITH STATEMENT使用 WITH STATEMENT 在 Oracle 中创建日历函数
【发布时间】:2022-11-18 07:44:46
【问题描述】:

我来自 MSSQL,有时我不熟悉 ORACLE 语法,我想创建一个将日期和日期数作为参数的函数并创建一个表函数。

我原来的查询是:

VAR TREND = 1;
VAR OBS_DATE = 20221109;
VAR N_DAYS = 21;

WITH CAL AS(
    SELECT
        TO_DATE(:OBS_DATE, 'YYYYMMDD') + (LEVEL - 1 * :TREND) DT, ROW_NUMBER() OVER(ORDER BY NULL) - 1 IX
    FROM DUAL
    WHERE TO_CHAR(TO_DATE(:OBS_DATE, 'YYYYMMDD') + (LEVEL - 1 * :TREND) , 'D') NOT IN (1,7)
    CONNECT BY LEVEL <= :N_DAYS + :N_DAYS/5*2+1
)
SELECT DT FROM CAL WHERE IX <= :N_DAYS
;

但是,当我尝试将其转换为函数时,它向我发送了一个错误,并指出正确的语法应该如何,我最初的尝试是:

CREATE OR REPLACE FUNCTION FUN_BUS_CALENDAR(
    OBS_DATE IN DATE := SYSDATE
    , NDAYS IN NUMBER
    , TREND IN NUMBER
    )
    RETURN OBS_DATE DATE;
    BEGIN

    WITH CAL AS(
        SELECT
            TO_DATE(:OBS_DATE, 'YYYYMMDD') + (LEVEL - 1 * :TREND) OBS_DATE, ROW_NUMBER() OVER(ORDER BY NULL) - 1 IX
        FROM DUAL
        WHERE TO_CHAR(TO_DATE(:OBS_DATE, 'YYYYMMDD') + (LEVEL - 1 * :TREND) , 'D') NOT IN (1,7)
        CONNECT BY LEVEL <= :N_DAYS + :N_DAYS/5.*2.+1.
    )
    SELECT OBS_DATE FROM CAL WHERE IX <= :N_DAYS
        RETURN OBS_DATE
    END 
/

【问题讨论】:

    标签: sql oracle user-defined-functions


    【解决方案1】:

    您可能应该只使用初始查询。

    但是,如果您确实想要一个函数,那么您可以使用流水线函数:

    CREATE FUNCTION BARRRAF.FUN_BUS_CALENDAR(
        OBS_DATE IN DATE := SYSDATE,
        NDAYS    IN NUMBER,
        TREND IN NUMBER
    ) RETURN SYS.ODCIDATELIST PIPELINED
    IS
    BEGIN
      FOR i IN 1 .. ndays LOOP
        PIPE ROW( obs_date + i - trend );
      END LOOP;
    END;
    /
    

    然后,如果你想生成一个行号,那么只需使用一个子查询:

    SELECT column_value AS obs_date,
           ROWNUM - 1 AS rn
    FROM   TABLE(BARRRAF.FUN_BUS_CALENDAR(ndays => 3, trend=>1))
    

    哪些输出:

    OBS_DATE RN
    2022-11-17 23:40:22 0
    2022-11-18 23:40:22 1
    2022-11-19 23:40:22 2

    fiddle

    【讨论】:

    • 在这种情况下如何避免周末??或参考带假期的表格?
    • @RafaBarragan 参见this answer
    猜你喜欢
    • 2011-07-22
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 2013-01-14
    • 2016-08-09
    相关资源
    最近更新 更多