Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment faire l'opération par lots en utilisant pl/sql

Je vais juste dire que c'est dégoûtant avant de commencer. Si vous créez des scripts qui automatisent la création de la base de données, j'abandonnerais la requête ci-dessous et je ferais simplement un copier/coller car c'est tellement horrible qu'il n'appartient PAS à vos scripts de déploiement de base de données.

La requête

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;
/

Qu'est-ce que cela fait ?

Fondamentalement, il obtient une liste de tables et construit dynamiquement le SQL pour effectuer les différentes tâches impliquées. EXECUTE IMMEDIATE prend la chaîne où nous avons construit le SQL et l'exécute. Le CHR(10) la méchanceté est une nouvelle ligne. Je voulais l'espace blanc là-dedans parce que je ne sais pas comment le laisser de côté affecterait l'analyse d'Oracle. Notez qu'à plusieurs endroits, nous concaténons le nom de la table directement à un autre texte pour générer une séquence ou un nom de contrainte PK.

Cela peut ou non générer une erreur si vous avez cité les noms de vos tables lors de la création et que vous utilisez des caractères minuscules. S'il sort une erreur, gardez à l'esprit que chaque instruction implique un commit. Une erreur signifie que le processus est à moitié terminé. Il échoue également si le schéma n'est pas l'utilisateur actuel. (Vous devrez modifier USER_TABLES à ALL_TABLES et ajoutez un filtre approprié dans la clause where et ajoutez le schéma devant le nom de la table lors de la construction du SQL pour le faire fonctionner sur un autre schéma.)

Un SQLFiddle qui fonctionne :http://sqlfiddle.com/#!4/b67fc/1 (Je ne peux pas croire que cela ait réellement fonctionné sur SQLFiddle.) Dans ce cas, la requête qui nous intéresse est terminée dans la définition du schéma puisque SQL Fiddle n'autorise que SELECT dans la requête.

Bonne chance. Vous en aurez besoin. Ne vous tirez pas une balle dans le pied.