0

我正在尝试使用 DBMS_JOB 安排作业(出于安全原因,我不能使用 DBMS_SCHEDULER),它使用 DDL 语句。

DECLARE
job_num NUMBER;
BEGIN
DBMS_JOB.SUBMIT(job => job_num,
what => 'BEGIN EXECUTE IMMEDIATE ''CREATE TABLE temp1 (ID NUMBER)''; END;'
);
DBMS_OUTPUT.PUT_LINE('JobID'||job_num);
DBMS_JOB.RUN(job_num);
END;
/

它无法执行给我一条错误消息:

ORA-12011:执行 1 个作业失败 ORA-06512:在“SYS.DBMS_IJOB”,第 548 行 ORA-06512:在“SYS.DBMS_JOB”,第 278 行 ORA-06512:在第 8 行

从匿名块中删除DBMS_JOB.RUN()语句后,我至少能够创建(并保存)作业。当我检查作业时,它已将其保存为 执行 BEGIN EXECUTE IMMEDIATE 'CREATE TABLE temp1 (id NUMBER) '; 结尾;

如果我独立执行它,它显然会执行。当我尝试通过调用 DBMS_JOB.RUN() 来执行整个事情时,它唯一一次失败了。

在 DBMS_JOB 中使用 DDL 语句作为参数是否有限制?我在文档中找不到任何指针。

4

1 回答 1

2

在回应其他评论者的观点时——动态创建表是一个危险信号,通常表明您确实应该使用全局临时表——有几个问题。

  1. DBMS_JOB.RUN您是否有需要致电的理由?您的调用DBMS_JOB.SUBMIT是告诉 Oracle 在父事务提交后立即异步运行该作业。所以,通常,你会打电话DBMS_JOB.SUBMIT,然后只是'COMMIT'。
  2. 提交作业的用户是否具有CREATE TABLE直接授予的权限?我的猜测是用户只有CREATE TABLE通过角色授予的权限。这将允许您以交互方式而不是在作业中运行匿名 PL/SQL 块。如果是这样,您将需要 DBA 直接授予您CREATE TABLE权限,而不是通过角色。
  3. 当作业失败时,会在警报日志中写入一条带有错误消息的条目。您(或者更有可能是 DBA)能否从警报日志中获取错误消息和错误堆栈并将其发布到此处(假设它不是来自 #2 的权限问题)。
于 2012-05-25T13:17:27.917 回答