0

试图创建一个程序,但我不断收到错误消息。这是代码

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:遇到符号“。” 预期以下情况之一时:

4

2 回答 2

1

可能只是错别字。这个版本应该可以工作(只要可以HK访问LAN.DOTS)。

PL/SQL 脚本与独立 SQL 的处理方式不同,因为它们需要尾随分号以及新行上的正斜杠。

SQL*Plus 中的斜线与分号语义有点奇怪。这是另一个关于这个问题的问题: 我什么时候需要在 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;
/
于 2019-07-09T15:46:40.357 回答
0

您发布的代码的结尾是这样的:

  end loop;
  HK.PURGE_LAN_DOTS;
END 

END缺少分号;但是上一行调用了这个过程,这将导致无限递归(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 replaceHK.前缀 - 但是所有者将设置为HK

因此,END应该只引用 PL/SQL 对象名称,并且不能有模式前缀:

create or replace procedure HK.PURGE_LAN_DOTS
...
  end loop;
END PURGE_LAN_DOTS;

不相关,但是:

deleteline timestamp := current_timestamp - 365;

将导致该current_timestamp值转换为减去 365 天的日期,然后将其转换回时间戳;这比必要的转换要多,并且会丢失小数秒。在这种情况下,您可能并不真正关心这一点,但有时它很重要。为了避免这两种情况,您可以执行以下任一操作:

deleteline timestamp := current_timestamp - interval '365' day;
deleteline timestamp := current_timestamp - 365 * interval '1' day;

一旦切换到间隔,您可能会想将其更改为current_timestamp - interval '1' year,但如果您在 2 月 29 日运行它,则会出现 ORA-01839 错误...

还要确保你真的想要current_timestamp而不是systimestamp

于 2019-07-09T15:46:54.580 回答