我有以下SQL代码:
INSERT INTO TIMES (saleDay, dayType)
SELECT saleDate, CASE WHEN h.hd IS NOT NULL THEN 'Holiday'
WHEN to_char(saleDate, 'd') IN (1,7) THEN 'Weekend'
ELSE 'Weekday' END dayType
FROM SALES s LEFT JOIN
(SELECT '01.01' hd FROM DUAL UNION ALL
SELECT '15.01' FROM DUAL UNION ALL
SELECT '19.01' FROM DUAL UNION ALL
SELECT '28.05' FROM DUAL UNION ALL
SELECT '04.07' FROM DUAL UNION ALL
SELECT '08.10' FROM DUAL UNION ALL
SELECT '11.11' FROM DUAL UNION ALL
SELECT '22.11' FROM DUAL UNION ALL
SELECT '25.12' FROM DUAL) h
ON h.hd = TO_CHAR(s.saleDate, 'dd.mm');
我需要将其转换为PL / SQL块。我最初只是将上面的代码转换为创建或替换过程,然后调用它,但我被要求在PL / SQL中完成上面的代码。
不幸的是,我在这个领域真的很挣扎,我仍然试图掌握PL / SQL的概念,特别是在这样的情况下,通过PL / SQL执行INSERT代码没有多大意义。有关将此转换为PL / SQL的最佳方法的指针/指令是什么?
谢谢!
答案 0 :(得分:3)
我同意,这比普通的SQL更好。如果这只是一个课程,我会用一个简单的循环和一个集合来做。如果您正在处理大批量生产环境,那么BULK COLLECT ... FORALL方法将具有更好的性能。
declare
vDayType varchar2(10);
TYPE Holidays is table of varchar2(5);
hd Holidays := Holidays('01.01','15.01','19.01','28.05','04.07','08.10','11.11','22.11','25.12');
begin
for s in (select distinct saleDate from Sales) loop
vDayType := case when TO_CHAR(s.saleDate, 'dd.mm') member of hd then
'Holiday'
when to_char(s.saleDate, 'd') IN (1,7) then
'Weekend'
else
'Weekday'
end;
insert into times (saleDay, dayType) values (s.saleDate, vDayType);
end loop;
end;
/
我觉得像这样的PL / SQL程序是一个很好的选择,因为需要对每个记录进行如此多的处理,以至于它在SQL中会很笨拙,不太可读或不可能。也许你正在构建HTML或修改clob列中的DOCX文件。我不知道。老实说,我在工作中经常不会遇到这种用例。
答案 1 :(得分:1)
我想我可能会这样......虽然我不确定它是否会被视为PL / SQL。
仍然欢迎更好的解决方案!
BEGIN
INSERT INTO TIMES (saleDay, dayType)
SELECT saleDate, CASE WHEN h.hd IS NOT NULL THEN 'Holiday'
WHEN to_char(saleDate, 'd') IN (1,7) THEN 'Weekend'
ELSE 'Weekday' END dayType
FROM SALES s LEFT JOIN
(SELECT '01.01' hd FROM DUAL UNION ALL
SELECT '15.01' FROM DUAL UNION ALL
SELECT '19.01' FROM DUAL UNION ALL
SELECT '28.05' FROM DUAL UNION ALL
SELECT '04.07' FROM DUAL UNION ALL
SELECT '08.10' FROM DUAL UNION ALL
SELECT '11.11' FROM DUAL UNION ALL
SELECT '22.11' FROM DUAL UNION ALL
SELECT '25.12' FROM DUAL) h
ON h.hd = TO_CHAR(s.saleDate, 'dd.mm');
END;
/
答案 2 :(得分:1)
如果TIMES表只有两列(salesDay和DayType),你也可以这样做,
BEGIN
FOR rec IN
(SELECT saleDate, CASE WHEN h.hd IS NOT NULL THEN 'Holiday'
WHEN to_char(saleDate, 'd') IN (1,7) THEN 'Weekend'
ELSE 'Weekday' END dayType
FROM SALES s LEFT JOIN
(SELECT '01.01' hd FROM DUAL UNION ALL
SELECT '15.01' FROM DUAL UNION ALL
SELECT '19.01' FROM DUAL UNION ALL
SELECT '28.05' FROM DUAL UNION ALL
SELECT '04.07' FROM DUAL UNION ALL
SELECT '08.10' FROM DUAL UNION ALL
SELECT '11.11' FROM DUAL UNION ALL
SELECT '22.11' FROM DUAL UNION ALL
SELECT '25.12' FROM DUAL) h
ON h.hd = TO_CHAR(s.saleDate, 'dd.mm')))
LOOP
INSERT INTO TIMES VALUES rec;
END LOOP;
END;
/
答案 3 :(得分:0)
我没有你的表,但我会做类似于下面显示的事情 - 创建一个表来接受插入(类似于你的)并使用SCOTT模式中的EMP表中的HIREDATE。
我看到kfinity刚刚发布了类似的答案;我仍在发帖,因为我觉得它更干净,但它的答案真的相同。
另外:像kfinity一样,将日期保存在嵌套表中是正确的方法(在代码顶部声明所有“神奇的东西”,因此如果需要,它们很容易找到并修改) ;但是,在您的课程中,您可能尚未涵盖馆藏。在我的解决方案中,我将值直接硬编码到需要它们的位置。
drop table my_table purge;
create table my_table ( hireday date, daytype varchar2(20) );
begin
for r in ( select hiredate from scott.emp )
loop
insert into my_table ( hireday, daytype ) values
( r.hiredate,
case when to_char(r.hiredate, 'dd.mm') in (
'01.01', '15.01', '19.01', '28.05', '04.07',
'08.10', '11.11', '22.11', '25.12') then 'Holiday'
when to_char(r.hiredate, 'd') in ('1', '7') then 'Weekend'
else 'Weekday' end
);
end loop;
end;
/