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

Plsql PL/SQL存储过程-IF-THEN-ELSE条件,plsql,oracle11g,Plsql,Oracle11g,我自己编写了存储过程,我这样做是为了自己的学习。这是针对数据仓库的,在这两个参数之间,表格将填充从起始年第一天到结束年最后一天的日期。我的存储过程将包含更多的列,但我想从一点一点开始,在构建代码时处理错误。因此,例如sp\u DATE\u D(20002001)当您在Application Express中为一行运行select语句时,它将返回以下 为一行运行SELECT语句时的期望值 日期=2000年1月1日 完整日期描述=2000年1月1日星期六 每周的第几天=6 上周的最后一天指标=Y--

我自己编写了存储过程,我这样做是为了自己的学习。这是针对数据仓库的,在这两个参数之间,表格将填充从起始年第一天到结束年最后一天的日期。我的存储过程将包含更多的列,但我想从一点一点开始,在构建代码时处理错误。因此,例如sp\u DATE\u D(20002001)当您在Application Express中为一行运行select语句时,它将返回以下

为一行运行SELECT语句时的期望值
日期=2000年1月1日
完整日期描述=2000年1月1日星期六
每周的第几天=6
上周的最后一天指标=Y--Y,如果是星期六,则为Y,其他指标为N。


表定义:

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;
/
创建或替换过程sp_DATE_D(v_START_YEAR IN INT,v_END_YEAR IN INT)作为
当前日期;
结束日期;
开始
v_当前日期:=截止日期(“0101”v|u开始日期“MMDDYYYY”);
结束日期:=截止日期('1231'|结束年份,'MMDDYYYY');
从日期中删除;

当v_CURRENT_DATE时,您试图在if/else表中插入第二行,我认为这不是您真正想要的。我不知道你为什么把
LAST\u DAY\u OF\u WEEK\u INDICATOR=
部分放在values子句中;也许您正在尝试更新,但(相当)对其语法感到困惑

如果条件永远不会匹配,则将日期转换为带有
day
的日期名称,该日期名称全部为大写。它还被填充为约会语言中最长的一天名称的长度,即英语中的星期三,因此你实际上必须与
星期六
(带尾随空格)进行比较,除非你包括在内;你假设打电话的人都有一个英语会话,这可能是本练习允许的

实际上,您希望只执行一次插入,而不是在插入之后执行更新。(我忽略了逐行方法的低效性,正如你所说,这是为了学习)。因此,可以将指示符列及其值作为现有插入的一部分。要在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()
允许您指定使用哪种语言作为日期和月份名称


请注意
FULL\u DATE\u DESCRIPTION
列中的填充,这会导致元素对齐。如果你想让它看起来更自然,也可以对该列的值使用FM修饰符。

它总是有助于解释你期望发生的事情和实际发生的事情,包括你收到的任何错误消息。@AlexPoole-我已经用期望和错误编辑了这篇文章。谢谢。解释也很清楚。