Plsql PL/SQL存储过程-IF-THEN-ELSE条件
我自己编写了存储过程,我这样做是为了自己的学习。这是针对数据仓库的,在这两个参数之间,表格将填充从起始年第一天到结束年最后一天的日期。我的存储过程将包含更多的列,但我想从一点一点开始,在构建代码时处理错误。因此,例如sp\u DATE\u D(20002001)当您在Application Express中为一行运行select语句时,它将返回以下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--
为一行运行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-我已经用期望和错误编辑了这篇文章。谢谢。解释也很清楚。