I have to make a monitor that detects invalid objects for different DBlinks.
I've tried with a code in different files for each DBLink
-- Enable logging of results to a specific file
SPOOL C:\route
SET SERVEROUTPUT ON
DECLARE
v_count NUMBER := 0;
-- Define a record type to store details of invalid objects
TYPE obj_details_type IS RECORD (
owner VARCHAR2(100),
object_name VARCHAR2(100),
status VARCHAR2(100),
object_type VARCHAR2(100)
);
-- Define a table type to store the details of invalid objects
TYPE obj_details_table IS TABLE OF obj_details_type;
-- Declare a variable to store details of invalid objects
obj_details_list obj_details_table := obj_details_table();
BEGIN
-- Get details of invalid objects
FOR obj IN (SELECT owner, object_name, status, object_type
FROM dba_objects@DBLINK
WHERE status = 'INVALID') LOOP
-- Increase the counter
v_count := v_count + 1;
-- Store details in a collection
obj_details_list.EXTEND;
obj_details_list(obj_details_list.LAST) := obj_details_type(obj.owner, obj.object_name, obj.status, obj.object_type);
END LOOP;
-- Show the number of invalid objects
DBMS_OUTPUT.PUT_LINE('No: of invalid objects: ' || v_count);
-- Show results as a table if there are invalid objects
IF v_count > 0 THEN
-- Print column headers with lines and separations
DBMS_OUTPUT.PUT_LINE('DBLINK: - DATE, TIME: ' || TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS'));
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------');
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------');
DBMS_OUTPUT.PUT_LINE('|' || RPAD('OWNER', 19) || '|' || RPAD('OBJECT NAME', 30) || '|' || RPAD('STATUS', 7) || ' |' || 'OBJECT TYPE' || ' |');
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------');
-- Show details of invalid objects stored in the collection
FOR i IN 1..obj_details_list.COUNT LOOP
-- Imprimir cada fila en formato tabular con líneas y separaciones
DBMS_OUTPUT.PUT_LINE('|' || RPAD(obj_details_list(i).owner, 19) || '|' || RPAD(obj_details_list(i).object_name, 30) || ' |' || RPAD(obj_details_list(i).status, 7) || ' |' || obj_details_list(i).object_type || ' |');
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------');
END LOOP;
ELSE
DBMS_OUTPUT.PUT_LINE('No invalid objects were found.');
END IF;
-- Close the database link
EXECUTE IMMEDIATE 'ALTER SESSION CLOSE DATABASE LINK DBLINK';
END;
/
SET SERVEROUTPUT OFF
-- Disable results recording
SPOOL OFF
the problem is that the log shows that, the max number of open-links is 4 that's why I added the EXECUTE IMMEDIATE 'ALTER SESSION CLOSE DATABASE LINK DBLINK in each file but the log shows:
ERROR in line 1:
ORA-02080: database link is in use
ORA-06512: in line 49
-- Define a record type to store details of invalid objects
*
ERROR in line 3:
ORA-04052: An error occurred while querying the remote object
DBLINK
ORA-00604: An error occurred at recursive SQL level 1
ORA-02020: too many database links in use
I was thinking if there was an easier way to make this to work by querying multiple DBLinks (I only have permissions to connect to database, data dictionary query and CREATE DATABASE LINK) I also want to know if there's a way of making the first code work whithout errors. Any ideas?