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日を。