【问题标题】:Procedure is not running程序未运行
【发布时间】:2020-11-28 11:20:05
【问题描述】:

我在查询下运行,给出错误。需要做什么才能得到请求的结果?

create or replace PROCEDURE data_cleanup_29th_nov_2020
IS
BEGIN

EXECUTE IMMEDIATE 'create table TEMP_ID_STAT_TIME_FRM_JOB_DOC as select JOB_ID, last_update_time_utc, status from J_DOC where 
LAST_UPDATE_TIME_UTC <= TRUNC(SYSDATE) - 30 and status=''Sent''';

  execute immediate 'delete from HUB_SIG where JOB_id IN ( SELECT JOB_ID
  FROM TEMP_ID_STAT_TIME_FRM_JOB_DOC)';

 execute immediate 'delete from J_DOC 
 where JOB_id IN ( SELECT JOB_ID
  FROM TEMP_ID_STAT_TIME_FRM_JOB_DOC)';

EXECUTE IMMEDIATE 'RENAME TABLE TEMP_ID_STAT_TIME_FRM_JOB_DOC TO TEMP_JOB_ID_FROM_JOB_DOC_1119';

END;

commit;

运行程序后出现以下错误

BEGIN
  data_cleanup_29th_nov_2020();
--rollback; 
END;

ORA-00955: 名称已被现有对象使用 ORA-06512:在“HUB.DATA_CLEANUP_29TH_NOV_2020”,第 7 行 ORA-06512: 在第 2 行 00955. 00000 - "名称已被现有对象使用

尝试使用以下查询:

CREATE OR REPLACE PROCEDURE ATAS_CLEANUP_NOV_2020 IS
BEGIN
    EXECUTE IMMEDIATE 'create table TEMP_ID_STAT_TIME_FRM_JOB_DOC as select JOB_ID, last_update_time_utc, status from J_DOC where 
LAST_UPDATE_TIME_UTC <= TRUNC(SYSDATE) - 30 and status=''Sent''';

    EXECUTE IMMEDIATE 'delete from HUB_SIGNATURE_DETAILS where JOB_id IN ( SELECT JOB_ID
  FROM TEMP_ID_STAT_TIME_FRM_JOB_DOC)';

    EXECUTE IMMEDIATE 'delete from J_DOC
 where JOB_id IN ( SELECT JOB_ID
  FROM TEMP_ID_STAT_TIME_FRM_JOB_DOC)';

    --EXECUTE IMMEDIATE 'RENAME TABLE TEMP_ID_STAT_TIME_FRM_JOB_DOC TO TEMP_JOB_ID_FROM_JOB_DOC_1119';
    BEGIN
        EXECUTE IMMEDIATE 'DROP TABLE TEMP_JOB_ID_FROM_JOB_DOC_1119';
    EXCEPTION
        WHEN OTHER THEN
            NULL;
    END;
    EXECUTE IMMEDIATE 'ALTER TABLE TEMP_ID_STAT_TIME_FRM_JOB_DOC RENAME TO TEMP_JOB_ID_FROM_JOB_DOC_1119';
END;

出现以下错误:

错误(14,5):PL/SQL:语句被忽略 错误(17,14):PLS-00201:必须声明标识符“OTHER”

试过了,它成功了:

CREATE OR REPLACE PROCEDURE ATAS_LATEST_DATA_cleanup_nov IS
BEGIN


    EXECUTE IMMEDIATE 'delete from HUB_SIG where JOB_id IN ( SELECT JOB_ID
  FROM TEMP_ID_STAT_TIME_FRM_JOB_DOC)';

    EXECUTE IMMEDIATE 'delete from J_DOC 
 where JOB_id IN ( SELECT JOB_ID
  FROM TEMP_ID_STAT_TIME_FRM_JOB_DOC)';

    --EXECUTE IMMEDIATE 'RENAME TABLE TEMP_ID_STAT_TIME_FRM_JOB_DOC TO TEMP_JOB_ID_FROM_JOB_DOC_1119';
   --BEGIN
     -- EXECUTE IMMEDIATE 'DROP TABLE TEMP_JOB_ID_FROM_JOB_DOC_1119';
    --EXCEPTION
      --  WHEN OTHER THEN
        --   NULL;
   -- END;
    EXECUTE IMMEDIATE 'ALTER TABLE TEMP_ID_STAT_TIME_FRM_JOB_DOC RENAME TO TEMP_JOB_ID_FROM_JOB_DOC_1119';
END;

COMMIT;

BEGIN
  ATAS_LATEST_DATA_cleanup_nov();
--rollback; 
END;

匿名块完成

在过程之外创建了临时表。 创建表 TEMP_JOB_ID_FROM_JOB_DOC_1119 作为 select JOB_ID, last_update_time_utc, status from J_DOC where LAST_UPDATE_TIME_UTC

在过程运行数据出现在 TEMP_JOB_ID_FROM_JOB_DOC_1119 之后,现在在过程中使用了临时表

现在我们必须实现以获取日期作为输入并传递它 重命名表时(RENAME TEMP_ID_STAT_TIME_FRM_JOB_DOC TO TEMP_JOB_ID_FROM_JOB_DOC_1119)

并在 DBMS_SCHEDULER 中安排此过程在每晚太平洋标准时间晚上 10 点运行。 我们该怎么做?

【问题讨论】:

  • 这个错误很容易解释,你不能创建一个具有特定名称的表,因为一个已经存在。也许您想使用不同的表名,或者您想插入现有表而不先创建它?一般认为,如果您将行插入(永久)全局临时表中,然后在最后将它们归档到常规表中,则这种事情看起来不需要任何动态 sql。
  • @BarbarosÖzhan 因为在程序运行之前表不(或不应该)存在,所以如果你不使用EXECUTE IMMEDITATE,那么它会在编译时从非现有表。
  • 这在第一次之后将不起作用,因为它引用了一个名为 TEMP_ID_STAT_TIME_FRM_JOB_DOC 的表,它在最后重命名为 TEMP_JOB_ID_FROM_JOB_DOC_1119。第二次运行它会失败,因为没有 TEMP_ID_STAT_TIME_FRM_JOB_DOC 表。

标签: sql oracle plsql oracle-sqldeveloper plsqldeveloper


【解决方案1】:

您的rename table 命令错误。

应该是:

ALTER TABLE TEMP_ID_STAT_TIME_FRM_JOB_DOC RENAME TO TEMP_JOB_ID_FROM_JOB_DOC_1119;

此外,您可以执行一次该过程,如果您再次执行它,它将在重命名命令处抛出错误。

现在,看看数据库中是否已经有任何可用的表。如果是,则在再次调用以下过程之前将其删除。

所以试试这个代码:

CREATE OR REPLACE PROCEDURE DATA_CLEANUP_29TH_NOV_2020
(P_IN_DATE IN DATE)
IS
BEGIN
    EXECUTE IMMEDIATE 'create table TEMP_ID_STAT_TIME_FRM_JOB_DOC as select JOB_ID, last_update_time_utc, status from J_DOC where 
LAST_UPDATE_TIME_UTC <= TRUNC(SYSDATE) - 30 and status=''Sent''';

    EXECUTE IMMEDIATE 'delete from HUB_SIG where JOB_id IN ( SELECT JOB_ID
  FROM TEMP_ID_STAT_TIME_FRM_JOB_DOC)';

    EXECUTE IMMEDIATE 'delete from J_DOC 
 where JOB_id IN ( SELECT JOB_ID
  FROM TEMP_ID_STAT_TIME_FRM_JOB_DOC)';

    --EXECUTE IMMEDIATE 'RENAME TABLE TEMP_ID_STAT_TIME_FRM_JOB_DOC TO TEMP_JOB_ID_FROM_JOB_DOC_1119';
    BEGIN
        EXECUTE IMMEDIATE 'DROP TABLE TEMP_JOB_ID_FROM_JOB_DOC_1119';
    EXCEPTION
        WHEN OTHER THEN
            NULL;
    END;
    EXECUTE IMMEDIATE 'ALTER TABLE TEMP_ID_STAT_TIME_FRM_JOB_DOC RENAME TO TEMP_JOB_ID_FROM_JOB_DOC_' || TO_CHAR(P_IN_DATE, 'MMYY');
END;
/

避免动态查询总是好的做法。

您可以在此过程之外创建一个表并使用它来存储临时数据。或者你可以使用全局临时表。

【讨论】:

  • 我们需要在程序内部自动化它们。我们必须获取日期作为输入并在重命名表时传递它(RENAME TEMP_ID_STAT_TIME_FRM_JOB_DOC TO TEMP_JOB_ID_FROM_JOB_DOC_1119)并在 DBMS_SCHEDULER 中安排此过程
  • 你也可以使用rename t1 to t2;(虽然不是rename table t1 to t2,因为OP最初尝试过)。
  • when others 缺少s
  • 我现在已经执行了这个过程,现在我们需要日期作为输入,并在重命名表时传递它(RENAME TEMP_ID_STAT_TIME_FRM_JOB_DOC TO TEMP_JOB_ID_FROM_JOB_DOC_1119)并在 DBMS_SCHEDULER 中安排这个过程
  • “我们必须将日期作为输入并在重命名表时传递它”然后我建议您的数据模型存在根本缺陷。日期本质上是一些业务数据,不应将其合并到对象名称中 - 表或过程名称。
【解决方案2】:

请检查“create table TEMP_ID_STAT_TIME_FRM_JOB_DOC”这个创建表语句,因为“TEMP_ID_STAT_TIME_FRM_JOB_DOC”已经存在于您的系统中。

【讨论】:

    猜你喜欢
    • 2013-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-06
    • 2021-10-17
    • 2018-10-13
    • 1970-01-01
    • 2013-07-01
    相关资源
    最近更新 更多