我编写了一个在 Oracle 9i 中运行的 PL/SQL 块,它通过 DB 链接处理来自 11g Oracle DB 的数据。但是代码需要永远完成。处理的数据大约是 1000 到 2000 条记录。我在这里发布代码:
DECLARE
v_last_comment VARCHAR2 (255);
v_check NUMBER := 0;
CURSOR noschedule_progs
IS
SELECT /*+ DRIVING_SITE(fcr) */
fcr.request_id,
DECODE
(fcpt.user_concurrent_program_name,
'Report Set', fcr.description,
'Request Set Stage', fcr.description,
fcpt.user_concurrent_program_name
) user_concurrent_program_name,
fcr.description, fcr.argument_text, fcr.concurrent_program_id,
fcr.parent_request_id, fcr.actual_start_date,
fcr.actual_completion_date,
ROUND ( (fcr.actual_completion_date - fcr.actual_start_date)
* 24
* 60,
4
) runtime,
'No Schedule' program_status, fu.user_name,
frt.responsibility_name, fcr.logfile_name
FROM apps.fnd_concurrent_requests@db_link fcr,
apps.fnd_concurrent_programs_tl@db_link fcpt,
apps.fnd_user@db_link fu,
apps.fnd_responsibility_tl@db_link frt
WHERE fcr.concurrent_program_id = fcpt.concurrent_program_id
AND fcr.requested_by = fu.user_id
AND fcr.responsibility_id = frt.responsibility_id
AND fcr.responsibility_application_id = frt.application_id
AND fcr.phase_code = 'C'
AND fcr.status_code IN ('C', 'G', 'E', 'X')
AND fcr.actual_completion_date >= SYSDATE - 1 / 24
AND fcr.request_id NOT IN (
SELECT NVL (parent_request_id, 1)
FROM apps.fnd_concurrent_requests@db_link)
AND fcr.requested_by = 1508715
AND fcr.request_id NOT IN (SELECT request_id
FROM allen.alert_main
WHERE program_status = 'No Schedule');
PROCEDURE check_schedule (p_request_id IN NUMBER)
IS
v_count NUMBER (2);
v_parent_id NUMBER (15);
v_last_updated_by NUMBER (15);
v_program VARCHAR2 (255);
v_parent_program VARCHAR2 (255);
v_description VARCHAR2 (255);
v_status VARCHAR2 (2);
BEGIN
SELECT NVL (MAX (phase_code), 'X')
INTO v_status
FROM apps.fnd_concurrent_requests@db_link
WHERE request_id = p_request_id;
IF v_status != 'R'
THEN
SELECT NVL (MAX (description), 'None')
INTO v_description
FROM apps.fnd_concurrent_requests@db_link
WHERE request_id = p_request_id;
SELECT COUNT (*)
INTO v_count
FROM apps.fnd_concurrent_requests@db_link
WHERE parent_request_id = p_request_id
AND concurrent_program_id =
(SELECT concurrent_program_id
FROM apps.fnd_concurrent_requests@db_link
WHERE request_id = p_request_id)
AND NVL (description, 'None') = v_description;
IF v_count = 0
THEN
SELECT NVL (MAX (parent_request_id), 1)
INTO v_parent_id
FROM apps.fnd_concurrent_requests@db_link
WHERE request_id = p_request_id;
SELECT NVL (MAX (last_updated_by), 0)
INTO v_last_updated_by
FROM apps.fnd_concurrent_requests@db_link
WHERE request_id = p_request_id;
IF v_parent_id = -1
THEN
IF v_last_updated_by != 4
THEN
INSERT INTO ikndba.rac_aso_alert_main
SELECT /*+ DRIVING_SITE(fcr) */
ikndba.rac_aso_alert_seq.NEXTVAL, fcr.request_id,
DECODE
(fcpt.user_concurrent_program_name,
'Report Set', fcr.description,
'Request Set Stage', fcr.description,
fcpt.user_concurrent_program_name
) user_concurrent_program_name,
fcr.argument_text, fcr.concurrent_program_id,
fcr.parent_request_id, fcr.actual_start_date,
fcr.actual_completion_date,
ROUND ( ( fcr.actual_completion_date
- fcr.actual_start_date
)
* 24
* 60,
4
) runtime,
'No Schedule' program_status, fu.user_name,
frt.responsibility_name, fcr.logfile_name,
SYSDATE, 'Program Not in Schedule', NULL, 'OPEN',
'SYSTEM'
FROM apps.fnd_concurrent_requests@db_link fcr,
apps.fnd_concurrent_programs_tl@db_link fcpt,
apps.fnd_user@db_link fu,
apps.fnd_responsibility_tl@db_link frt
WHERE fcr.concurrent_program_id =
fcpt.concurrent_program_id
AND fcr.requested_by = fu.user_id
AND fcr.responsibility_id = frt.responsibility_id
AND fcr.responsibility_application_id =
frt.application_id
AND fcr.request_id = p_request_id
AND fcr.request_id NOT IN (
SELECT request_id
FROM allen.alert_main
WHERE program_status = 'No Schedule');
commit
END IF;
ELSE
SELECT NVL (MAX (DECODE (fcpt.user_concurrent_program_name,
'Report Set', fcr.description,
'Request Set Stage', fcr.description,
fcpt.user_concurrent_program_name
)
),
'Purged'
)
INTO v_program
FROM apps.fnd_concurrent_requests@db_link fcr,
apps.fnd_concurrent_programs_tl@db_link fcpt
WHERE request_id = p_request_id
AND fcr.concurrent_program_id = fcpt.concurrent_program_id;
SELECT NVL (MAX (DECODE (fcpt.user_concurrent_program_name,
'Report Set', fcr.description,
'Request Set Stage', fcr.description,
fcpt.user_concurrent_program_name
)
),
'Purged'
)
INTO v_parent_program
FROM apps.fnd_concurrent_requests@db_link fcr,
apps.fnd_concurrent_programs_tl@db_link fcpt
WHERE request_id = v_parent_id
AND fcr.concurrent_program_id = fcpt.concurrent_program_id;
IF v_parent_program = v_program AND v_program != 'Purged'
THEN
INSERT INTO ikndba.rac_aso_alert_main
SELECT /*+ DRIVING_SITE(fcr) */
ikndba.rac_aso_alert_seq.NEXTVAL, fcr.request_id,
DECODE
(fcpt.user_concurrent_program_name,
'Report Set', fcr.description,
'Request Set Stage', fcr.description,
fcpt.user_concurrent_program_name
) user_concurrent_program_name,
fcr.argument_text, fcr.concurrent_program_id,
fcr.parent_request_id, fcr.actual_start_date,
fcr.actual_completion_date,
ROUND ( ( fcr.actual_completion_date
- fcr.actual_start_date
)
* 24
* 60,
4
) runtime,
'No Schedule' program_status, fu.user_name,
frt.responsibility_name, fcr.logfile_name,
SYSDATE, 'Program Not in Schedule', NULL, 'OPEN',
'SYSTEM'
FROM apps.fnd_concurrent_requests@db_link fcr,
apps.fnd_concurrent_programs_tl@db_link fcpt,
apps.fnd_user@db_link fu,
apps.fnd_responsibility_tl@db_link frt
WHERE fcr.concurrent_program_id =
fcpt.concurrent_program_id
AND fcr.requested_by = fu.user_id
AND fcr.responsibility_id = frt.responsibility_id
AND fcr.responsibility_application_id =
frt.application_id
AND fcr.request_id = p_request_id
AND fcr.request_id NOT IN (
SELECT request_id
FROM allen.alert_main
WHERE program_status =
'No Schedule');
COMMIT;
ELSE
SELECT NVL (MAX (parent_request_id), 1)
INTO v_parent_id
FROM apps.fnd_concurrent_requests@db_link
WHERE request_id =v_parent_id;
check_schedule (v_parent_id);
END IF;
END IF;
END IF;
END IF;
END;
BEGIN
FOR noschedule_progs_row IN noschedule_progs
LOOP
check_schedule (noschedule_progs_row.request_id);
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK;
DBMS_OUTPUT.put_line (SQLCODE);
END;
/
有没有办法提高这个程序的效率?