试图创建一个程序,但我不断收到错误消息。这是代码
create or replace procedure HK.PURGE_LAN_DOTS
AS
batchsize number := 15000;
deleteline timestamp := current_timestamp - 365;
counter number := 0;
BEGIN
loop
DELETE FROM LAN.DOTS
WHERE rownum <= batchsize
AND TIMESTAMP < deleteline;
COMMIT;
counter:=counter + SQL%rowcount;
exit when batchsize > SQL%rowcount;
end loop;
HK.PURGE_LAN_DOTS;
END
这是我得到的错误
错误(36,12):PLS-00103:遇到符号“。”当期望以下之一时:;
答案 0 :(得分:1)
可能只是错别字。此版本应该有效(只要HK
可以访问LAN.DOTS
)。
PL / SQL脚本与独立SQL的区别在于,它们既需要尾随分号,又需要在新行上使用正斜杠。
SQL * Plus中的斜线vs.分号语义有点奇怪。这是另一个正好被问到的问题: When do I need to use a semicolon vs a slash in Oracle SQL?
最后,当您可能打算使用HK.PURGE_LAN_DOTS;
时,在END
语句之前包括了END PURGE_LAN_DOTS;
。
请注意,您不能在该结束标记中包含模式名称,并且命名结束标记是完全可选的(您只能使用END;
)。
create or replace procedure HK.PURGE_LAN_DOTS
AS
batchsize number := 15000;
deleteline timestamp := current_timestamp - 365;
counter number := 0;
BEGIN
loop
DELETE FROM LAN.DOTS
WHERE rownum <= batchsize
AND TIMESTAMP < deleteline;
COMMIT;
counter:=counter + SQL%rowcount;
exit when batchsize > SQL%rowcount;
end loop;
END PURGE_LAN_DOTS;
/
答案 1 :(得分:0)
您发布的代码末尾有以下内容:
end loop;
HK.PURGE_LAN_DOTS;
END
END
缺少分号;但是前一行调用 this 过程,这将导致无限递归(Oracle最终将终止该过程)。
我认为您在发布时损坏了此文件,而您实际上拥有:
end loop;
END HK.PURGE_LAN_DOTS;
现在该错误是有道理的(尽管报告行和列的编号不太正确)。
尽管create语句具有可选的模式前缀:
create or replace procedure HK.PURGE_LAN_DOTS
匹配的END
没有。整个语句可以被认为是SQL和PL / SQL的混合-达到的程度与触发器不同,但此处的效果相似。该语句确实做了很多事情-它在该模式下创建了一个名为PURGE_LAN_DOTS
的过程类型对象,并使用相同的名称编译和存储了代码的PL / SQL部分。 HK.
位不是对象名称的一部分,并且与PL / SQL引擎无关-END
是纯PL / SQL。如果您查看all_source
视图,将会看到存储的源将是PROCEDURE PURGE_LAN_DOTS AS ...
,而没有create or replace
或HK.
前缀-所有者将被设置为{ {1}}。
因此,HK
应该仅引用PL / SQL对象名称,并且不能具有架构前缀:
END
不相关,但是:
create or replace procedure HK.PURGE_LAN_DOTS
...
end loop;
END PURGE_LAN_DOTS;
会将deleteline timestamp := current_timestamp - 365;
值转换为减去365天的日期,然后将其转换回时间戳;这比必要的转换要多,并且浪费了小数秒。在这种情况下,您可能并不十分在意,但有时很重要。为避免两者,您可以执行以下任一操作:
current_timestamp
一旦切换到间隔,您可能会尝试将其更改为deleteline timestamp := current_timestamp - interval '365' day;
deleteline timestamp := current_timestamp - 365 * interval '1' day;
,但是如果您在2月29日运行它,ORA-01839将会出错...
还要确保您确实要current_timestamp - interval '1' year
而不是current_timestamp
。