无法弄清楚为什么我在这个存储过程的第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;
答案 0 :(得分:1)
我不知道你为什么会得到同义词错误。但这是一些应该是单个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;
如果你愿意的话,你可以抛出你的重试逻辑。
如果我错过了一些与你正在做的不同的微妙之处,请道歉。
答案 1 :(得分:0)
SELECT table_owner, table_name, db_link
FROM dba_synonyms
WHERE owner = 'PUBLIC' and db_link is not null
返回0行 据我所知,没有同义词.......