我自己编写了存储过程,并且这样做是为了我自己的学习。这适用于数据仓库,正在发生的事情是,在两个参数之间,表格将填充从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语句
答案 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()
的第三个参数允许您指定用于日期和月份名称的语言。
注意FULL_DATE_DESCRIPTION
列中的填充,这会导致元素对齐。如果您希望它看起来更自然,也可以使用FM修饰符作为该列值。