我是PL / SQL的新手,我正在尝试创建一个存储过程,该过程将使用以下代码填充表:
DROP TABLE Times CASCADE CONSTRAINTS;
CREATE TABLE Times (
sale_day DATE NOT NULL,
day_type VARCHAR2(50) NOT NULL,
PRIMARY KEY (sale_day));
CREATE OR REPLACE PROCEDURE Time_Procedure
AS
l_sale_date date;
temp_value varchar2(5);
CURSOR c1 IS SELECT SALE_DATE FROM SALES;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO l_sale_date;
EXIT WHEN c1%NOTFOUND;
SELECT to_char(to_date(l_sale_date), 'DY') into temp_value from
dual;
IF l_sale_date LIKE '01-JAN-%' OR l_sale_date LIKE '21-JAN-%' OR
l_sale_date LIKE '18-FEB-%' OR l_sale_date LIKE '28-MAY-%'
OR l_sale_date LIKE '04-JUL-%' OR l_sale_date LIKE '03-SEP-%' OR
l_sale_date LIKE '08-OCT-%' OR l_sale_date LIKE '11-NOV-%'
OR l_sale_date LIKE '22-NOV-%' OR l_sale_date LIKE '25-DEC-%'
THEN
INSERT INTO Times values(l_sale_date,'Holiday');
ELSE IF temp_value='MON' OR temp_value ='TUE' OR temp_value='WED' OR
temp_value='THU' OR temp_Value='FRI' THEN
INSERT INTO Times values(l_sale_date,'Weekday');
ELSE
INSERT INTO Time values(l_sale_date,'Weekend');
END IF;
END LOOP;
CLOSE c1;
END;
/
但我一直收到以下错误:
LINE / COL ERROR
20/1 PL / SQL:忽略SQL语句
20/13 PL / SQL:ORA-00942:表或视图不存在
我一直在关注这个问题,并且无法弄清楚我的代码有什么问题导致错误。
答案 0 :(得分:1)
ORA-00942:表或视图不存在
你有一个拼写错误:第三个INSERT语句是
INSERT INTO Time
而其他陈述是
INSERT INTO Times
问题标题中的错误原因不同:
遇到符号“文件结束”错误
表示语法错误。这一行
ELSE IF
告诉PL / SQL编译器你正在创建一个嵌套的IF语句。所以它期望END IF匹配该IF加上外部块的END IF。像这样:
IF l_sale_date LIKE '01-JAN-%'
...
ELSE IF temp_value='MON'
...
ELSE -- this goes with the nested IF
...
END IF; -- this goes with the nested IF
END IF; -- this is the clause you're missing
然而,您似乎只是想尝试实施标准的单级切换。在这种情况下,您需要知道PL / SQL是ELSIF而不是ELSE IF。像这样:
IF l_sale_date LIKE '01-JAN-%'
...
ELSIF temp_value='MON'
...
ELSE -- this goes with the starting IF
...
END IF;
或者,您可能希望使用CASE语句,该语句具有相同的结构,但更符合其他编程语言。
CASE
WHEN l_sale_date LIKE '01-JAN-%'
...
WHEN temp_value='MON'
...
ELSE
...
END CASE;
答案 1 :(得分:1)
以下是固定版本 - times
不是time
,to_char
不是to_date
,elsif
不是else if
等等。我也改变了它以使用游标FOR循环而不是所有打开,获取和关闭,将temp_value
移动到游标中并给它一个正确的名称(语义就是这个作业中的所有内容),并替换了{ {1}}列出了方便的or
结构。自从你开始以来,你甚至可能会避免养成大写编码的习惯,这会让我们的行业感到悲伤。
in ()
但是,您不应该假设日期格式或语言。有一天,该程序可能会被有西班牙语桌面设置的人调用,周末的日子将是'SÁB'和'DOM'而不是'SAT'和'SUN',默认日期格式可能是create or replace procedure time_procedure
as
begin
for r in (
select sale_date, to_date(sale_date, 'DY') as day_name
from sales
)
loop
if r.sale_date like '01-JAN-%'
or r.sale_date like '21-JAN-%'
or r.sale_date like '18-FEB-%'
or r.sale_date like '28-MAY-%'
or r.sale_date like '04-JUL-%'
or r.sale_date like '03-SEP-%'
or r.sale_date like '08-OCT-%'
or r.sale_date like '11-NOV-%'
or r.sale_date like '22-NOV-%'
or r.sale_date like '25-DEC-%'
then
insert into times(sale_day, day_type)
values (r.sale_date, 'Holiday');
elsif r.day_name in ('MON','TUE','WED','THU','FRI') then
insert into times(sale_day, day_type)
values (r.sale_date, 'Weekday');
else
insert into times(sale_day, day_type)
values (r.sale_date,'Weekend');
end if;
end loop;
end;
或其他什么。
另外,如果我们将日期名称缩短为一个字母并指定英语,那么周末日期只是YYYY-MM-DD
,所以这里是重构版本:
'S'
如果这不是PL / SQL的学习练习,你可以在SQL中完成整个过程:
create or replace procedure time_procedure
as
begin
for r in (
select sale_date
, to_char(sale_date,'DD-MM') as date_str
, substr(to_char(sale_date, 'DY', 'nls_date_language = English'),1,1) as day_name
from sales
)
loop
if r.date_str in
( '01-01'
, '21-01'
, '18-02'
, '28-05'
, '04-07'
, '03-09'
, '08-10'
, '11-11'
, '22-11'
, '25-12' )
then
insert into times(sale_day, day_type)
values (r.sale_date, 'Holiday');
elsif r.day_name = 'S' then
insert into times(sale_day, day_type)
values (r.sale_date,'Weekend');
else
insert into times(sale_day, day_type)
values (r.sale_date, 'Weekday');
end if;
end loop;
end;