PL/SQL 存储过程 - IF THEN ELSE 条件

PL/SQL Stored Procedure - IF THEN ELSE condition

存储过程是我自己写的,也是为了自己的学习。这是针对数据仓库的,发生的情况是在两个参数之间 table 将填充从 START_YEAR 第一天到 END_YEAR 最后一天的日期。我的存储过程将包含更多列,但我打算一点一点地开始,并在构建代码时处理错误。因此,例如 sp_DATE_D(2000,2001) 并且当您 运行 在 Application Express 中为一行 select 语句时,它 returns以下

当我 运行 一行的 SELECT 语句时的预期
DATE_KEY = 2000 年 1 月 1 日
FULL_DATE_DESCRIPTION = 2000 年 1 月 1 日星期六
DAY_OF_WEEK = 6
LAST_DAY_OF_WEEK_INDICATOR = Y -- 如果是星期六则为 Y,对于其他所有情况则为 N。


Table定义:

CREATE TABLE DATE_D
(  
    DATE_KEY DATE NOT NULL,
    FULL_DATE_DESCRIPTION VARCHAR2(64) NOT NULL,
    DAY_OF_WEEK NUMBER(1,0) NOT NULL,
    LAST_DAY_OF_WEEK_INDICATOR CHAR(1) NOT NULL,
    CONSTRAINT DATE_D_PK PRIMARY KEY (DATE_KEY)
);

存储过程:
我知道有一个条件需要实施,只是不确定在哪里。我尝试了 IF THEN ELSE,但没有成功。

CREATE OR REPLACE PROCEDURE sp_DATE_D(v_START_YEAR IN INT, v_END_YEAR IN INT) AS

v_CURRENT_DATE DATE;
v_END_DATE DATE;

BEGIN

v_CURRENT_DATE := TO_DATE('0101' || v_START_YEAR, 'MMDDYYYY');
v_END_DATE     := TO_DATE('1231' || v_END_YEAR, 'MMDDYYYY');

DELETE FROM DATE_D;

WHILE v_CURRENT_DATE <= v_END_DATE 
LOOP
INSERT INTO DATE_D
(
    DATE_KEY, 
    FULL_DATE_DESCRIPTION,
    DAY_OF_WEEK
)   
VALUES
(
    v_CURRENT_DATE,
    TO_CHAR(v_CURRENT_DATE, 'Day, Month DD, YYYY'),
    TO_NUMBER(TO_CHAR(v_CURRENT_DATE,'D')) - 1
);
BEGIN
   IF TO_CHAR(v_CURRENT_DATE,'DAY') != 'Saturday' THEN
    INSERT INTO DATE_D (LAST_DAY_OF_WEEK_INDICATOR) values(LAST_DAY_OF_WEEK_INDICATOR = 'N');       
   ELSE     
    INSERT INTO DATE_D(LAST_DAY_OF_WEEK_INDICATOR) values(LAST_DAY_OF_WEEK_INDICATOR = 'Y');
   END IF;
END;


v_CURRENT_DATE := v_CURRENT_DATE + 1;

END LOOP;
END;
/


错误
编译失败,第 49 行 (17:03:53)
PL/SQL: ORA-00917: 缺少逗号编译失败,第 49 行 (17:03:53)
PL/SQL:SQL 语句 ignoredCompilation 失败,第 51 行 (17:03:53)
PL/SQL: ORA-00917: 缺少逗号编译失败,第 51 行 (17:03:53)
PL/SQL: SQL 语句被忽略

您正试图在 if/else 的 table 中插入第二行,我认为这不是您真正想要的。我不确定您为什么将 LAST_DAY_OF_WEEK_INDICATOR = 部分放在 values 子句中;也许您正在尝试更新,但对它的语法(相当)感到困惑。

虽然永远不会匹配 if 条件,但您将日期转换为带有 DAY 的日期名称,这会为您提供全大写的日期名称。它也被填充到你的日期语言中最长的一天名称的长度,即英语中的星期三,所以你实际上必须与 SATURDAY(尾随 space)进行比较,除非你包括 an FM format modifier;并且您假设调用它的人将进行英语会话,这对于本练习可能是允许的。

您真的只想执行一次插入,而不是先插入再更新。 (我忽略了逐行方法的低效率,因为你说这是有意学习的)。因此,您可以将指示符列及其值作为现有插入的一部分。要在 SQL 语句中执行 if/else,您可以使用 decode 或 case 表达式:

...
  LOOP
    INSERT INTO DATE_D
    (
      DATE_KEY, 
      FULL_DATE_DESCRIPTION,
      DAY_OF_WEEK,
      LAST_DAY_OF_WEEK_INDICATOR
    )   
    VALUES
    (
      v_CURRENT_DATE,
      TO_CHAR(v_CURRENT_DATE, 'Day, Month DD, YYYY'),
      TO_NUMBER(TO_CHAR(v_CURRENT_DATE,'D')) - 1,
      CASE 
        WHEN TO_CHAR(v_CURRENT_DATE,'FMDay') = 'Saturday' THEN 'Y'
        ELSE 'N'
      END
    );
    v_CURRENT_DATE := v_CURRENT_DATE + 1;
  END LOOP;
END;
/

如果您确实想要允许使用不同的会话语言,那么 to_char() 有第三个参数,它允许您指定用于日期和月份名称的语言。

SQL Fiddle demo.

请注意 FULL_DATE_DESCRIPTION 列中的填充,这会导致元素对齐。如果您希望它看起来更自然,也可以对该列值使用 FM 修饰符。