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é.