始める前に、これはひどいことだと言っておきます。データベースの作成を自動化するスクリプトを作成している場合は、以下のクエリを捨てて、コピー/貼り付けを使用します。これは非常に恐ろしいため、データベース展開スクリプトには属しません。
クエリ
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;
/
これは何をしますか?
基本的に、テーブルのリストを取得し、関連するさまざまなタスクを実行するために SQL を動的に構築します。EXECUTE IMMEDIATE
SQL を作成して実行する文字列を取得します。意地悪はCHR(10)
改行です。空白を除外するとOracleの解析にどのように影響するかがわからないため、そこに空白が必要でした。いくつかの場所で、テーブル名を他のテキストに直接連結して、シーケンスまたは PK 制約名を生成していることに注意してください。
作成中にテーブル名を引用し、いくつかの小文字を使用している場合、これはエラーになる場合とならない場合があります。エラーが発生する場合は、すべてのステートメントにコミットが含まれていることに注意してください。エラーは、プロセスが半分完了したことを意味します。スキーマが現在のユーザーでない場合も失敗します。(別のスキーマで機能するように SQL を作成するときに、where 句に適切なフィルターを変更USER_TABLES
しALL_TABLES
て追加し、テーブル名の前にスキーマを追加する必要があります。)
実際に動作する SQLFiddle: http://sqlfiddle.com/#!4/b67fc/1 (これが実際に SQLFiddle で動作するとは信じられません)。 FiddleSELECT
はクエリでのみ許可されます。
幸運を。必要になります。足を撃たないでください。