1

階層クエリに問題があります。次のような自己参照テーブルがあります。

    id    parent_id    name    size
-----------------------------------------
    1       null       Ship1    50
    2        1         cabin1   10
    3        1         cabin2   30
    4        3         shelf1    5
    5        3         shelf2   20
    6       null       Ship2    50
    7        6         cabin1   10
    8        6         cabin2   30
    9        7         shelf1   15

データベースにトリガーを追加して、ユーザーがその船の残りのサイズを超えるキャビンを追加できないようにする必要があります。

たとえば、テーブルでは、船 1 の合計サイズは 50 です。サイズ 40 を消費するキャビンが 2 つあります。したがって、使用可能なスペースとして 10 が残ります。サイズが 10 を超える別のキャビンを追加することはできません。<= 10 であれば問題ありません。キャビンや棚も同様です。キャビン内のすべての棚の合計サイズは、そのキャビンに割り当てられた合計サイズを超えてはなりません。

テーブル (ルート) には、任意の数の出荷エントリを含めることができます。

私は階層的なクエリについて知っており、ツリーをたどることができますが、問題について自分の考えをまとめるのが難しいと感じています。そのトリガーを正常に追加できるように、誰かが私を正しい方向に向けてもらえますか?

4

1 に答える 1

1

ミニマリストの目的とメンテナンスの容易さ(アーカイブ/パージなど)のために、おそらくShips、 、Cabinsおよびに別々のテーブルを用意する必要があるという@N_westに同意します。Shelvesこれを処理するトリガーが必要な場合は、トリガーをSHIPS使用してログ テーブルからデータを取得し、ログ テーブルSHIPSのデータを使用して挿入に対して検証する必要がありますSHIPS。それは最善の解決策ではありませんが、あなたが望むものを達成することができます. ALERTSエラー コード (20101) に基づいて、アプリケーションで処理するユーザー定義の例外を設定できます。

SQL> CREATE TABLE LOG_SHIPS AS SELECT * FROM SHIPS;

SQL> CREATE or REPLACE TRIGGER TRG_SHIP
BEFORE INSERT ON SHIPS
FOR EACH ROW

L_count   NUMBER(10);
L_total   NUMBER(10);
e_exp     EXCEPTION;

BEGIN
     SELECT sum(size) INTO L_count
       FROM LOG_SHIPS
      WHERE parent_id = :new.parent_id;

     SELECT size INTO L_total
       FROM LOG_SHIPS
      WHERE id = :new.parent_id;

     if L_count+:new.size > L_total then
        RAISE e_exp;
     else
        INSERT INTO LOG_SHIPS VALUES (:new.id,:new.parent_id,:new.name,:new.size);
     end if;

EXCEPTION
   WHEN e_exp THEN
     RAISE_APPLICATION_ERROR (-20101,'Size entered exceeds limit.');
   WHEN others THEN
      null; -- do some meaningful exception handling here
END;
/

別のアプローチはCOMPOUND TRIGGERS、Oracle 11g を使用している場合にのみ使用することです。

于 2012-08-04T18:04:00.353 に答える