2017-11-23 10 views
0

私のデータベースには「プロジェクト」という表があり、「マイルストーン」と呼ばれる表があります。 "Project"の主キーはProjectIDという列です。関係「マイルストーン」には、「番号」と呼ばれる主キーと、それが属するプロジェクトを参照する外部キーがあります。OracleSQL:別の列に応じて自動インクリメント(弱エンティティ・モデリング)

「マイルストーン」に新しいエントリを挿入すると、プライマリキー「番号」が自動的にインクリメントされますが、プロジェクトに関連して新しいマイルストーンが属します。

 Milestone 
ProjectID | Number 
    69    1 
    69    2 
    69    3 
    420   1 
    420   2 
    666   1 
    420   3 

それは「マイルストーン」テーブル内の値を挿入するトリガーを使用してOracleSQLでこれを実現することが可能である:アイデアは、基本的には次のでしょうか?

答えて

0

最初に、Oracleの列NUMBERを命名することは、基本数値型の名前であるため、間違いがあります。私はあなたが賢くなり、代わりにPROJECT_LINEと呼ぶと仮定します。

複合トリガを使用してこれを実行できます。 BEFORE STATEMENTのトリガポイントでは、すべてのプロジェクトの最大プロジェクトラインをキャプチャします(これは、プロジェクトを参照していることを知らない前文セクションにあるためです)、BEFORE EACH ROWトリガポイントに最大値+ 1新PROJECT_LINEに、プロジェクトの最大値のライン更新:私はこれを行うの効率を保証しません

CREATE OR REPLACE TRIGGER MILESTONE_TRG 
    FOR INSERT ON MILESTONE 
COMPOUND TRIGGER 
    TYPE NUMBER_MAP IS TABLE OF NUMBER 
    INDEX BY PLS_INTEGER; 
    tblMAX_PROJECT_LINE NUMBER_MAP; -- store max PROJECT_LINE, indexed by PROJECT_ID 

    BEFORE STATEMENT IS 
    BEGIN 
    tblMAX_PROJECT_LINE := NUMBER_MAP(); 

    FOR aRow IN (SELECT PROJECT_ID, 
         MAX(PROJECT_LINE) AS MAX_PROJECT_LINE 
        FROM MILESTONE 
        GROUP BY PROJECT_LINE) 
    LOOP 
     tblMAX_PROJECT_LINE(aRow.PROJECT_ID) := aRow.MAX_PROJECT_LINE; 
    END LOOP; 
    END BEFORE STATEMENT; 

    BEFORE EACH ROW IS 
    BEGIN 
    :NEW.PROJECT_LINE := tblMAX_PROJECT_LINE(:NEW.PROJECT_ID) + 1; 
    tblMAX_PROJECT_LINE(:NEW.PROJECT_ID) := tblMAX_PROJECT_LINE(:NEW.PROJECT_ID) + 1; 
    END AFTER EACH ROW; 
END MILESTONE_TRG; 

を。また、同時に複数のINSERTが衝突する可能性があります。 (PROJECT_ID、PROJECT_LINE)にPRIMARY KEYまたはUNIQUE制約を設定し、INSERTステートメントで発生する可能性があるキー違反例外をトラップし、INSERTを再試行する必要があります。

幸運のベスト。

+0

ご挨拶ありがとうございました。私が幸いなことに、「数字」の列については、英語の単語を使用していませんでしたが、私は列の名前を「数字」にしました。しかし、あなたが私に示したコードは完全には機能していません。新しいMilestoneエントリを挿入しようとすると、「トリガが無効で再検証に失敗しました」というエラーが表示されます。 – Infecto

+0

StackOverflowのすべてのコードと同様に、状況に応じてデバッグを少し行う必要があります。明らかに、トリガーのコードにエラーがあります。エラーを調べるには、以下を実行します: 'SELECT * FROM ALL_ERRORS WHERE OWNER = 'トリガーオーナー'と 'NAME ='トリガー名 'ORDER BY SEQUENCE'、トリガー名を' trigger name''に置き換えますトリガーが作成されたスキーマで '' owner ''をトリガーします。運が良かった。 –

関連する問題