23ai: Domains ändern
In einigen vorangegangenen Beiträgen haben wir bereits die in Oracle Database 23ai neu eingeführten Domains näher vorgestellt.
Dort haben wir auch darauf hingewiesen, dass Domains nicht einfach geändert werden können, man kann sie lediglich löschen und neu anlegen. Eine Domain kann aber nicht einfach gelöscht werden, wenn sie irgendwo verwendet wird.
MARCO @ DB23AI:PDB1:>drop domain dom_phone;
Error starting at line : 1 in command -
drop domain dom_phone
Error report -
ORA-11502: The domain DOM_PHONE to be dropped has dependent objects.
Help: docs.oracle.com/error-help/db/ora-11502/
11502. 0000 - "The domain %s to be dropped has dependent objects."
*Cause: An attempt is made to drop a domain with dependent objects.
*Action: Drop the domain using the FORCE mode
Die Lösung scheint naheliegend und findet sich in der Fehlermeldung bereits wieder. Man soll die FORCE Option verwenden. Das funktioniert dann auch.
MARCO @ DB23AI:PDB1:>drop domain if exists dom_phone force;
Domain DOM_PHONE dropped.
Doch damit sind dann auch alle Constraints, die eventuell auf den betroffenen Spalten definiert waren, mit verschwunden. Also noch mal einen Schritt zurück. Besser wir verwenden die Option FORCE PRESERVE, denn die löscht zwar die Domain und hebt die Abhängigkeit der Spalten von der Domain auf, behält aber zumindest die Constraints bei. Damit ist die Datenintegrität nach wie vor gesichert.
MARCO @ DB23AI:PDB1:>drop domain dom_phone force preserve;
Domain DOM_PHONE dropped.
Jetzt kann die Domain mit neuen bzw. aktualisierten Einstellungen neu erstellt werden. Wir müssen nur noch die Verknüpfung der Spalten zur Domain wiederherstellen. Doch Moment, welche Spalten waren jetzt welcher Domain zugeordnet? Das bekommen wir im nachhinein nicht mehr raus. Also ist es wichtig, diese Information vor dem DROP einzusammeln. Dabei hilft dieses kleine SQL-Schnippsel.
MARCO @ DB23AI:PDB1:>select 'alter table "'||owner||'"."'||table_name||'" modify ("' || column_name || '" domain "' || domain_owner || '"."' || domain_name ||'");' dom_ddl
2 from all_tab_columns
3* where domain_name='DOM_PHONE' order by TABLE_NAME, COLUMN_ID ;
DOM_DDL
_________________________________________________________________________________________________________________________
alter table "MARCO"."PHONES" modify ("PHONE" domain "MARCO"."DOM_PHONE");
alter table "MARCO"."PHONES" modify ("MOBILE" domain "MARCO"."DOM_PHONE");
Nach der Neuanlage der Domain stellt man mit diesen generierten Befehlen die Verknüpfung zur Domain wieder her. Voraussetzung ist natürlich, dass die Datentypen etc. noch zusammenpassen. Andernfalls muss man die Tabelle im Vorfeld noch entsprechend aktualisieren.
Kommentare
Keine Kommentare