DBMS_JOB中的DDL语句

我正在尝试使用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语句作为参数有限制吗?我无法在文档中找到任何指针。

0
额外 编辑
意见: 1
添加了我得到的错误消息“始终”
额外 作者 Incognito,
我必须创建的实际表名称不称为“TEMP”。我只是用它在这里发布这个问题。另外,我的实际意图是仅创建一个临时表,而不是表。我没有太大的灵活性,因为我正在修改应用程序的某个部分,并且“不愿意”必须通过这种方法。
额外 作者 Incognito,
我从来没有听说过“总是”的错误消息...
额外 作者 Jeffrey Kemp,
无法重现。它适用于我(在11gR2中测试),并且该作业按预期创建了“TEMP”表。
额外 作者 Jeffrey Kemp,
+1对Aldridge的评论 - 动态创建表通常是一个糟糕的系统设计的标志。
额外 作者 Jeffrey Kemp,
您能否扩展阻止您使用DBMS_Scheduler的安全原因?另外,你看过使用全局临时表吗?看到一个名为TEMP的表正在创建,它有点红旗。
额外 作者 David Aldridge,

1 答案

虽然回应其他评论者的观点 - 即时创建表格是一个红旗,通常表明你确实应该使用全局临时表格 - 几个问题。

  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的权限问题)。
2
额外
谢谢Justin。这有很大帮助。我将首先与DBA检查创建表的权限!
额外 作者 Incognito,