PL / SQL存储过程 - 如果那么ELSE条件

时间:2015-02-18 21:20:55

标签: plsql oracle11g

我自己编写了存储过程,并且这样做是为了我自己的学习。这适用于数据仓库,正在发生的事情是,在两个参数之间,表格将填充从START_YEAR的第一天到END_YEAR的最后一天的日期。我的存储过程将包含更多列,但我想逐步开始并在构建代码时处理错误。例如, sp_DATE_D(2000,2001),当您在Application Express中为一行运行select语句时,它将返回以下内容

当我运行一行的SELECT语句时的预期
DATE_KEY = 01/01/2000
FULL_DATE_DESCRIPTION = 2000年1月1日星期六
DAY_OF_WEEK = 6
LAST_DAY_OF_WEEK_INDICATOR = 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)
);

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

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语句ignoreCompilation failed,第51行(17:03:53)
PL / SQL:ORA-00917:缺少逗号编译失败,第51行(17:03:53)
PL / SQL:忽略SQL语句

1 个答案:

答案 0 :(得分:0)

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

if条件永远不会匹配,你将日期转换为DAY的日期名称,它会以大写形式显示日期名称。它也会填充到您日期语言中最长日期名称的长度,即英语星期三,因此您实际上必须与SATURDAY(带尾随空格)进行比较,除非您包含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修饰符作为该列值。