- problemy ze scalaniem schematów, występujące w wyniku rotacji użytkowników baz danych
- redundancja danych i problemy związane z identyfikacją biznesowego znaczenia obiektów o takiej samej nazwie
- kłopoty z utrzymaniem spójności kodu i odwołaniami do obiektów powtarzających się w wielu schematach
- nadmierne zużycie przestrzeni dyskowej
CREATE TABLE DUAL AS
SELECT * FROM DUAL
UNION
SELECT * FROM DUAL
RENAME myTable TO DUAL
Trigger TRG_CHECK_DUPLICATES jest przykładem rozwiązania omawianego problemu. Został napisany przy następujących założeniach:
- nie działa dla użytkowników SYS i SYSTEM
- działa przed operacjami CREATE i RENAME
- dla operacji RENAME dokonujemy prostej analizy polecenia DDL, dla polecenia CREATE nazwa obiektu pobierana jest z predefiniowanej zmiennej ORA_DICT_OBJ_NAME
- w komunikacie wyjątku podawane są nazwy już istniejących obiektów dla instrukcji DDL
- jest instalowany przez DBA w schemacie SYS
CREATE OR REPLACE TRIGGER SYS.TRG_CHECK_DUPLICATES
BEFORE CREATE
OR RENAME
ON DATABASE
DECLARE
CURSOR C (pc_ObjectName VARCHAR2) IS
SELECT OWNER|| '.' || OBJECT_NAME || ' typu ' || OBJECT_TYPE AS MSG FROM DBA_OBJECTS
WHERE OBJECT_NAME = pc_ObjectName
AND OWNER <> ORA_DICT_OBJ_OWNER;
vc_ErrorMsg VARCHAR2(500 CHAR);
vc_SQLStatement VARCHAR2(200 CHAR);
vc_ObjectName VARCHAR2(30 CHAR);
vt_List DBMS_STANDARD.ORA_NAME_LIST_T := DBMS_STANDARD.ORA_NAME_LIST_T();
vn_Size PLS_INTEGER;
BEGIN
IF USER IN ('SYS', 'SYSTEM') THEN
RETURN;
END IF;
BEGIN
IF ORA_SYSEVENT = 'RENAME' THEN
vn_Size := ora_sql_txt (vt_List);
FOR i IN 1 .. vn_Size
LOOP
vc_SQLStatement := vc_SQLStatement || vt_List (i);
END LOOP;
vc_ObjectName := REGEXP_SUBSTR(TRIM(vc_SQLStatement), '[[:alnum:]]+[[:cntrl:]]*$',1,1);
vc_ObjectName := REGEXP_SUBSTR(TRIM(vc_ObjectName), '[[:alnum:]]+',1,1);
ELSIF ORA_SYSEVENT = 'CREATE' THEN
vc_ObjectName:= ORA_DICT_OBJ_NAME;
END IF;
FOR EL IN C(vc_ObjectName)
LOOP
IF vc_ErrorMsg IS NULL THEN
vc_ErrorMsg := 'istnieje już ' || CHR(13) || CHR(10) || EL.MSG;
ELSE
vc_ErrorMsg := vc_ErrorMsg || CHR(13) || CHR(10) || EL.MSG ;
END IF;
END LOOP;
EXCEPTION WHEN OTHERS THEN
NULL;
END;
IF vc_ErrorMsg IS NOT NULL THEN
RAISE_APPLICATION_ERROR(-20101, 'Zdublowane nazwy obiektów: ' || vc_ErrorMsg );
END IF;
END;
/