Jag ska bara säga att det här är grymt innan jag börjar. Om du skapar skript som automatiserar skapandet av databasen, skulle jag avstå från nedanstående fråga och bara kopiera/klistra in eftersom det här är så hemskt att det INTE hör hemma i dina skript för databasdistribution.
Frågan
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;
/
Vad gör det här?
I grund och botten får den en lista med tabeller och bygger dynamiskt SQL för att utföra de olika uppgifterna som är involverade. EXECUTE IMMEDIATE
tar strängen där vi byggde SQL och kör den. CHR(10)
otäckhet är en nyrad. Jag ville ha blanktecken där eftersom jag inte vet hur att utelämna det skulle påverka Oracles analys. Observera att vi på flera ställen sammanfogar tabellnamnet direkt till någon annan text för att generera ett sekvens- eller PK-begränsningsnamn.
Detta kan eller kanske inte felas om du citerade dina tabellnamn när du skapade och använder några små bokstäver. Om det GÅR fel, kom ihåg att varje påstående innebär en commit. Ett fel innebär att processen är halvklar. Det misslyckas också om schemat inte är den aktuella användaren. (Du måste ändra USER_TABLES
till ALL_TABLES
och lägg till ett lämpligt filter i where-satsen och lägg till schemat framför tabellnamnet när du bygger SQL för att få det att fungera på ett annat schema.)
En verklig fungerande SQLFiddle:http://sqlfiddle.com/#!4/b67fc/1 (Jag kan inte tro att detta faktiskt fungerade på SQLFiddle.) I det här fallet är frågan vi är intresserade av över i schemadefinitionen eftersom SQL Fiddle bara tillåter SELECT
i frågan.
Lycka till. Du kommer att behöva det. Skjut inte dig själv i foten.