sql >> Databáze >  >> RDS >> Oracle

Jak provést dávkovou operaci pomocí pl/sql

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.




  1. PostgreSQL:Auto-inkrement založený na vícesloupcovém jedinečném omezení

  2. MYSQL:Aktualizujte pole se spojením více polí

  3. SQL dotaz k sečtení dat

  4. MariaDB JSON_MERGE_PRESERVE() Vysvětleno