Po prostu powiem, że to jest obrzydliwe, zanim zacznę. Jeśli tworzysz skrypty, które automatyzują tworzenie bazy danych, porzucę poniższe zapytanie i po prostu przejdę do kopiowania/wklejania, ponieważ jest to tak okropne, że NIE należy do skryptów wdrażania bazy danych.
Zapytanie
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;
/
Co to robi?
Zasadniczo pobiera listę tabel i dynamicznie buduje SQL, aby wykonać różne zadania. EXECUTE IMMEDIATE
pobiera ciąg znaków, w którym zbudowaliśmy kod SQL, i wykonuje go. CHR(10)
złośliwość to nowa linia. Chciałem tam umieścić białą spację, ponieważ nie wiem, jak pominięcie jej wpłynęłoby na parsowanie Oracle. Zauważ, że w kilku miejscach łączymy nazwę tabeli bezpośrednio z innym tekstem, aby wygenerować sekwencję lub nazwę ograniczenia PK.
Może się to nie udać, ale nie musi, jeśli podczas tworzenia zacytowałeś nazwy tabel i używasz małych liter. Jeśli WYKRYWA błąd, pamiętaj, że każda instrukcja obejmuje zatwierdzenie. Błąd będzie oznaczał, że proces jest w połowie zakończony. Nie powiedzie się również, jeśli schemat nie jest bieżącym użytkownikiem. (Musisz zmienić USER_TABLES
do ALL_TABLES
i dodaj odpowiedni filtr w klauzuli WHERE i dodaj schemat przed nazwą tabeli podczas budowania SQL, aby działał na innym schemacie.)
Rzeczywiste działające SQLFiddle:http://sqlfiddle.com/#!4/b67fc/1 (Nie mogę uwierzyć, że to faktycznie zadziałało w SQLFiddle.) W tym przypadku zapytanie, które nas interesuje, jest zakończone w definicji schematu, ponieważ SQL Fiddle pozwala tylko na SELECT
w zapytaniu.
Powodzenia. Będziesz tego potrzebować. Nie strzelaj sobie w stopę.