Než začnu, řeknu, že je to hnusné. Pokud vytváříte skripty, které automatizují vytváření databáze, upustil bych od níže uvedeného dotazu a přešel na kopírování/vkládání, protože je to tak hrozné, že NEPATŘÍ do skriptů pro nasazení databáze.
Dotaz
DECLARE
CURSOR TABLES IS SELECT * FROM USER_TABLES
WHERE 0 = (SELECT COUNT(*)
FROM USER_CONSTRAINTS
WHERE USER_CONSTRAINTS.TABLE_NAME = USER_TABLES.TABLE_NAME
AND USER_CONSTRAINTS.CONSTRAINT_TYPE = 'P'
);
BEGIN
FOR T IN TABLES LOOP
EXECUTE IMMEDIATE 'ALTER TABLE '||T.TABLE_NAME||' ADD ID NUMBER(12)';
EXECUTE IMMEDIATE 'CREATE SEQUENCE '||T.TABLE_NAME||'Seq START WITH 1';
EXECUTE IMMEDIATE 'UPDATE '||T.TABLE_NAME||' SET ID = '||T.TABLE_NAME||'Seq.NEXTVAL';
EXECUTE IMMEDIATE 'ALTER TABLE '||T.TABLE_NAME||' ADD PRIMARY KEY (ID)';
EXECUTE IMMEDIATE 'CREATE OR REPLACE TRIGGER '||T.TABLE_NAME||'PKSet '||CHR(10)
||'BEFORE INSERT ON '||T.TABLE_NAME||' '||CHR(10)
||'FOR EACH ROW '||CHR(10)
||'BEGIN '||CHR(10)
||':NEW.ID := '||T.TABLE_NAME||'Seq.NEXTVAL; '||CHR(10)
||'END; ';
END LOOP;
END;
/
Co to dělá?
V podstatě získá seznam tabulek a dynamicky sestaví SQL, aby mohl provádět různé související úkoly. EXECUTE IMMEDIATE
vezme řetězec, ve kterém jsme vytvořili SQL, a spustí jej. CHR(10)
ohavnost je nový řádek. Chtěl jsem tam mezery, protože nevím, jak by jejich vynechání ovlivnilo analýzu Oracle. Všimněte si, že na několika místech zřetězujeme název tabulky přímo s jiným textem, abychom vygenerovali název sekvence nebo omezení PK.
To může nebo nemusí být chybou, pokud jste během vytváření uváděli názvy tabulek a používáte malá písmena. Pokud dojde k chybě, mějte na paměti, že každý příkaz zahrnuje potvrzení. Chyba bude znamenat, že proces je z poloviny hotový. Také se nezdaří, pokud schéma není aktuální uživatel. (Budete muset změnit USER_TABLES
do ALL_TABLES
a přidejte vhodný filtr do klauzule where a přidejte schéma před název tabulky při sestavování SQL, aby fungovalo na jiném schématu.)
Skutečně fungující SQLFiddle:http://sqlfiddle.com/#!4/b67fc/1 (Nemůžu uvěřit, že to na SQLFiddle skutečně fungovalo.) V tomto případě je dotaz, který nás zajímá, v definici schématu ukončen, protože SQL Fiddle umožňuje pouze SELECT
v dotazu.
Hodně štěstí. Budeš to potřebovat. Nestřílejte se do nohy.