oracle ORA-01775: 同义词循环链,但没有同义词

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/253881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 17:25:55  来源:igfitidea点击:

ORA-01775: looping chain of synonyms but there are no synonyms

oraclestored-procedures

提问by Dave Costa

Can't figure out why I'm getting 'SQL Statement ignored' and 'ORA-01775: looping chain of synonyms' on line 52 of this stored procedure. Got any ideas?

无法弄清楚为什么我在此存储过程的第 52 行收到“SQL 语句被忽略”和“ORA-01775:同义词循环链”。有什么想法吗?

CREATE OR REPLACE PACKAGE PURGE_LOG_BY_EVENT_DAYS AS

  TYPE dual_cursorType IS REF CURSOR RETURN dual%ROWTYPE;

  PROCEDURE log_master_by_event_days (event_id NUMBER, purge_recs_older_than NUMBER, result_cursor OUT dual_cursorType);


END PURGE_LOG_BY_EVENT_DAYS;

/


CREATE OR REPLACE PACKAGE BODY PURGE_LOG_BY_EVENT_DAYS
AS

  err_msg     VARCHAR2(4000);

  PROCEDURE log_master_by_event_days (event_id NUMBER, purge_recs_older_than NUMBER, result_cursor OUT dual_cursorType)
  IS

  TYPE  type_rowid IS TABLE OF ROWID INDEX BY BINARY_INTEGER;
  TYPE  type_ref_cur IS REF CURSOR;

  l_rid                   type_rowid;
  c1                      type_ref_cur;

  l_sql_stmt              VARCHAR2(4000);
  proc_start_time         DATE := sysdate;
  purge_date              DATE;

  l_bulk_collect_limit    NUMBER := 1000;
  retry                   NUMBER := 5;
  retry_count             NUMBER := 0; 
  loop_count              NUMBER := 0;

  err_code                VARCHAR2(10);


BEGIN

  purge_date := to_date(sysdate - purge_recs_older_than);

  l_sql_stmt := '';
  l_sql_stmt := l_sql_stmt ||' SELECT rowid FROM LOG_MASTER ';
  l_sql_stmt := l_sql_stmt ||'  WHERE last_changed_date < :purge_date';
  l_sql_stmt := l_sql_stmt ||'    AND event_id = :event_id';


  -- The following while loop
  -- executes the purge code
  -- 'retry' number of times in case of ORA-01555

  WHILE retry > 0 LOOP

    BEGIN

      -- START of purge code
      OPEN c1 FOR l_sql_stmt USING purge_date, event_id;
      LOOP

        FETCH c1 BULK COLLECT into l_rid LIMIT l_bulk_collect_limit;

        FORALL i IN 1..l_rid.COUNT
          DELETE from log_master
           WHERE rowid = l_rid(i);
        COMMIT;

        loop_count := loop_count + 1;
        EXIT WHEN c1%NOTFOUND;

      END LOOP;
      CLOSE c1;

      -- End of purge code
      -- if processing reached this point
      -- Process completed successfuly, set retry = 0 to exit loop
      retry := 0;

    EXCEPTION
    WHEN OTHERS THEN
      -- ====================================
      -- Get error msg
      -- ====================================

      ROLLBACK;
      err_code := sqlcode;

      dbms_output.put_line(err_code);

      -- ====================================
      -- Check if it is 01555
      -- if so retry, else exit loop
      -- ====================================

      retry := retry - 1;
      if err_code = '-1555' and retry > 0 THEN
        CLOSE c1;
        retry_count :=  retry_count + 1;
      else
        err_msg := sqlerrm;
        exit;
      end if;
    END;
  END LOOP;


  IF err_msg IS NULL THEN


    open result_cursor for select '1 - PURGE_LOG_BY_EVENT_DAYS ran successfully (event_id : '||event_id||', loop_count : '||loop_count||', bulk_limit : '||l_bulk_collect_limit||', retries : '||retry_count||') ' from dual;


  ELSE


    open result_cursor for select '2 - PURGE_LOG_BY_EVENT_DAYS After (event_id : '||event_id||', loop_count : '||loop_count||', bulk_limit : '||l_bulk_collect_limit||', retries : '||retry_count||') with Error: ' || err_msg from dual;


  END IF;

 END log_master_by_event_days;


END PURGE_LOG_BY_EVENT_DAYS;

回答by Dave Costa

I have no idea why you're getting the synonym error. But that's a lot of code for something that should be a single DELETE statement. I assume you've changed it to commit-every-n to avoid rollback errors. It would be nice if you could get your DBA to increase the undo space so you can actually do the work you need to do. Failing that, I think you can still make it much simpler:

我不知道你为什么会收到同义词错误。但是对于应该是单个 DELETE 语句的东西来说,这是很多代码。我假设您已将其更改为 commit-every-n 以避免回滚错误。如果您能让您的 DBA 增加撤消空间,这样您就可以真正完成您需要做的工作,那就太好了。如果做不到这一点,我认为你仍然可以让它变得更简单:

LOOP
  DELETE FROM log_master
    WHERE last_changed_date < :purge_date
      AND event_id = :event_id
      AND rownum <= :batch_delete_limit
    USING purge_date, event_id, l_bulk_collect_limit;
  EXIT WHEN SQL%NOTFOUND;
END LOOP;

And you can throw your retry logic around that if you want.

如果你愿意,你可以抛出你的重试逻辑。

Apologies if I've missed some subtlety that makes this different from what you're doing.

如果我错过了一些使这与您正在做的事情不同的微妙之处,请道歉。

回答by Dave Costa

SELECT table_owner, table_name, db_link
  FROM dba_synonyms 
 WHERE owner        = 'PUBLIC' and db_link is not null

returns 0 rows as far as i know, there are no synonyms.......

据我所知返回 0 行,没有同义词......