Jeg vil bare sige, at det er grimt, før jeg starter. Hvis du opretter scripts, der automatiserer oprettelsen af databasen, ville jeg droppe nedenstående forespørgsel og bare kopiere/indsætte, fordi det er så forfærdeligt, at det IKKE hører hjemme i dine databaseimplementeringsscripts.
Forespørgslen
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;
/
Hvad gør dette?
Grundlæggende får den en liste over tabeller og bygger dynamisk SQL'en til at udføre de forskellige involverede opgaver. EXECUTE IMMEDIATE
tager strengen, hvor vi byggede SQL'en, og udfører den. CHR(10)
grimhed er en ny linje. Jeg ville have hvidrummet derinde, fordi jeg ikke ved, hvordan det ville påvirke Oracles parsing at udelade det. Bemærk, at vi flere steder sammenkæder tabelnavnet direkte til en anden tekst for at generere et sekvens- eller PK-begrænsningsnavn.
Dette kan eller kan ikke fejle, hvis du citerede dine tabelnavne under oprettelsen og bruger nogle små bogstaver. Hvis det ER fejl, skal du huske på, at hver erklæring involverer en forpligtelse. En fejl vil betyde, at processen er halvt færdig. Det mislykkes også, hvis skemaet ikke er den aktuelle bruger. (Du skal ændre USER_TABLES
til ALL_TABLES
og tilføj et passende filter i where-sætningen og tilføj skemaet foran tabelnavnet, når du bygger SQL'en for at få det til at fungere på et andet skema.)
En faktisk fungerende SQLFiddle:http://sqlfiddle.com/#!4/b67fc/1 (Jeg kan ikke tro, at dette faktisk virkede på SQLFiddle.) I dette tilfælde er den forespørgsel, vi er interesseret i, forbi i skemadefinitionen, da SQL Fiddle kun tillader SELECT
i forespørgslen.
Held og lykke. Du får brug for det. Skyd ikke dig selv i foden.