Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como fazer a operação em lote usando pl/sql


Só vou dizer que isso é nojento antes de começar. Se você estiver criando scripts que automatizam a criação do banco de dados, eu abandonaria a consulta abaixo e apenas copiaria/colaria porque isso é tão horrível que NÃO pertence aos scripts de implantação do banco de dados.

A consulta

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

O que isso faz?


Basicamente, ele obtém uma lista de tabelas e constrói dinamicamente o SQL para realizar as diversas tarefas envolvidas. EXECUTE IMMEDIATE pega a string onde construímos o SQL e a executa. O CHR(10) maldade é uma nova linha. Eu queria o espaço em branco lá porque não sei como deixá-lo de fora afetaria a análise do Oracle. Observe que em vários lugares nós concatenamos o nome da tabela diretamente para algum outro texto para gerar uma sequência ou nome de restrição PK.

Isso pode ou não dar erro se você citou seus nomes de tabela durante a criação e estiver usando alguns caracteres minúsculos. Se der erro, tenha em mente que cada declaração envolve um commit. Um erro significa que o processo está pela metade. Também falhará se o esquema não for o usuário atual. (Você precisará alterar USER_TABLES para ALL_TABLES e adicione um filtro apropriado na cláusula where e adicione o esquema na frente do nome da tabela ao construir o SQL para fazê-lo funcionar em outro esquema.)

Um SQLFiddle de trabalho real:http://sqlfiddle.com/#!4/b67fc/1 (Não posso acreditar que isso realmente funcionou no SQLFiddle.) Nesse caso, a consulta em que estamos interessados ​​está na definição do esquema, pois o SQL Fiddle permite apenas SELECT na consulta.

Boa sorte. Você vai precisar. Não dê um tiro no pé.