1

多くのテーブルに主キーを追加する必要があり、stackoverflow から (1 つのテーブルに対して) 次のスクリプトを取得しました。

ALTER TABLE table1 ADD ID NUMBER(12);
CREATE SEQUENCE table1Seq START WITH 1;
UPDATE table1 SET table1ID = table1Seq.NEXTVAL;
ALTER TABLE table1 ADD PRIMARY KEY (ID);
CREATE OR REPLACE TRIGGER table1PKSet
BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
  :NEW.ID := table1Seq.NEXTVAL;
END;
/

ただし、ユーザーのすべてのテーブルに対して同じ操作を行う必要があります。

pl/sql を使用して、ユーザーのすべてのテーブルをループし、上記の操作を実行できるのでしょうか?

4

1 に答える 1

5

始める前に、これはひどいことだと言っておきます。データベースの作成を自動化するスクリプトを作成している場合は、以下のクエリを捨てて、コピー/貼り付けを使用します。これは非常に恐ろしいため、データベース展開スクリプトには属しません。

クエリ

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 IMMEDIATESQL を作成して実行する文字列を取得します。意地悪はCHR(10)改行です。空白を除外するとOracleの解析にどのように影響するかがわからないため、そこに空白が必要でした。いくつかの場所で、テーブル名を他のテキストに直接連結して、シーケンスまたは PK 制約名を生成していることに注意してください。

作成中にテーブル名を引用し、いくつかの小文字を使用している場合、これはエラーになる場合とならない場合があります。エラーが発生する場合は、すべてのステートメントにコミットが含まれていることに注意してください。エラーは、プロセスが半分完了したことを意味します。スキーマが現在のユーザーでない場合も失敗します。(別のスキーマで機能するように SQL を作成するときに、where 句に適切なフィルターを変更USER_TABLESALL_TABLESて追加し、テーブル名の前にスキーマを追加する必要があります。)

実際に動作する SQLFiddle: http://sqlfiddle.com/#!4/b67fc/1 (これが実際に SQLFiddle で動作するとは信じられません)。 FiddleSELECTはクエリでのみ許可されます。

幸運を。必要になります。足を撃たないでください。

于 2013-05-29T01:10:33.800 に答える