3

USERNAME、USER_SESSIONS、および TOOLBOX_DIRS_REGISTERED の 3 つのデータベース テーブルを定義しようとしています。最初の 2 つは問題なく定義できますが、最後の 1 つは少し残念です。理想的には、以下のコード ブロックに示すように定義したいと思いますが、チェック制約内でサブクエリを使用できないと思いますか?

すぐ下のコード ブロックは、テーブル TOOLBOX_DIRS_REGISTERED を定義する方法を示しています。コード ブロックの先頭には、テーブル定義で使用される特定の制約についての私の考えを説明しようとするコメントも含まれています。

-- Constraint : USERNAME_FK
-- ========================
--
-- USERNAME must contain a username which has been added to the table USERNAME.
--
-- Constraint : USER_SESSION_ID_FK
-- ===============================
--
-- USER_SESSION_ID must contain a user session ID which has been added to the table 
-- USER_SESSION.
--
-- Constraint : check_user_session_id
-- ==================================
--
-- In addition to the above constraint, USER_SESSION_ID must also belong to the 
-- username which is contained within USERNAME.

create table
TOOLBOX_DIRS_REGISTERED
(
 DIRNAME         varchar2(100) not null,
 USERNAME        varchar2(32)  not null,
 USER_SESSION_ID varchar2(32)  not null,
 AUTO_REGISTER   char          not null,
 constraint
   TOOLBOX_DIRS_REGISTERED_PK
   primary key (DIRNAME),
 constraint
   USERNAME_FK
   foreign key (USERNAME)
   references USERS(USERNAME),
 constraint
   USER_SESSION_ID_FK
   foreign key (USER_SESSION_ID)
   references USER_SESSIONS(USER_SESSION_ID),
 constraint
   check_user_session_id
   check
   (
    USERNAME in
    (
     select USERNAME from USER_SESSIONS
     where USER_SESSIONS(USER_SESSION_ID) = USER_SESSION_ID
    )
   )
);

この問題を回避する方法、つまりチェック制約「check_user_session_id」の定義でサブクエリを使用する方法を知っている人はいますか? この特定の状況では、サブクエリの代わりにマテリアライズド ビューを使用できることを Stackoverflow で読みました。問題は、マテリアライズド ビューを使用する場合、チェック制約が実行された時点でそれが最新であることを確認する必要があることです。だから私がしたことは、マテリアライズドビューでdbms_mview.refreshを呼び出すトリガーとともにマテリアライズドビューを実装することでした。Oracle がトリガーで COMMIT できないと不平を言うことを除いて、これはすべて問題ありません。うーん!それが私に与える正確なメッセージは次のとおりです。

ERROR at line 2:
ORA-04092: cannot COMMIT in a trigger
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2760
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2740
ORA-06512: at "SYSTEM.SIMULAB_MVIEW", line 19
ORA-06512: at "SYSTEM.TRIG_TOOLBOX_DIRS_REGISTERED", line 3
ORA-04088: error during execution of trigger 'SYSTEM.TRIG_TOOLBOX_DIRS_REGISTERED'

マテリアライズド ビューを更新した後、オラクルが自動的にコミットを実行しようとしていると思いますが、それが不満なのですか?

私のトリガーは次のように定義されています。

create or replace trigger TRIG_TOOLBOX_DIRS_REGISTERED
  before insert or update on
    TOOLBOX_DIRS_REGISTERED
  begin

    -- Invoke the PL/SQL Package procedure simulab_mview.refresh_mview

    simulab_mview.refresh_mview;

  end;

PL/SQL パッケージ simulab_mview は次のように定義されています。

create or replace
package
simulab_mview
as

    procedure
    refresh_mview;

end;
/

create or replace package body
simulab_mview
as

    procedure
    refresh_mview
    as

    begin

        -- I have a strong suspicion that dbms_mview.refresh might cause a commit to 
        -- be executed. This would make sense, as the RDBMS would need to execute a 
        -- commit so that other clients could see the result of the refresh.

        dbms_mview.refresh('mat_view', 'C');

    end;

end;
/

誰もこれについて何か考えがありますか?私がやりたいことを行うためのより簡単な方法はありますか?具体化されたビューを使用しないでください。トリガーを使用しないでください。

これに関する助けや考えさえあれば、非常に高く評価されます。誰かが本当にこの問題について助けや考えを提供できるなら、私は彼らの支援に前もって感謝したいと思います.

良い1日を。

4

2 に答える 2

1

私がこれを正しく理解していれば、表と表toolbox_dirs_registeredの両方を参照したくないと思います。それは正規化されていません。テーブルを参照するだけで、既にテーブルへの参照があります。usersuser_sessionsuser_sessionsusers

次のスニペットはテストされておらず、多くのカット アンド ペーストがありますが、アイデアは得られると思います。

CREATE TABLE users(
   user_id  NUMBER
  ,username VARCHAR2(32)
  ,CONSTRAINT users_pk PRIMARY KEY(user_id)
);

CREATE UNIQUE INDEX users_username_uk ON users(username);


CREATE TABLE user_sessions(
   user_session_id NUMBER
  ,user_id         NUMBER
  ,session_id      NUMBER
  ,CONSTRAINT user_sessions_pk PRIMARY KEY(user_session_id)
  ,CONSTRAINT user_session_user_id_fk FOREIGN KEY(user_id) REFERENCES users(user_id)
);

CREATE UNIQUE INDEX user_sessions_user_session_uk ON user_sessions(user_id, session_id);


CREATE TABLE toolbox_dirs_registered(
   dirname         VARCHAR2(100) NOT NULL
  ,user_session_id NUMBER(32)
  ,auto_register   CHAR(1)
  ,CONSTRAINT toolbox_dirs_registered_pk PRIMARY KEY(dirname)
  ,CONSTRAINT tdr_user_session_id_fk FOREIGN KEY(user_session_id) REFERENCES user_sessions(user_session_id)
);
于 2012-08-06T02:09:00.070 に答える