0

テーブル構造を以下に示すトリガーを使用して、ユーザーがデータベースにログインした合計時間を計算しようとしています。

create table stats$user_log
(
   user_id           varchar2(30),
   session_id           number(8),
   host              varchar2(30),
   logon_day                 date,
   logon_time        varchar2(10),
   logoff_day                date,
   logoff_time       varchar2(10),
   elapsed_minutes       varchar2(32)
);

ログオンのトリガーは次のとおりです。

create or replace trigger
   logon_audit_trigger
AFTER LOGON ON DATABASE
BEGIN
insert into stats$user_log values(
   user,
   sys_context('USERENV','SESSIONID'),
   sys_context('USERENV','HOST'),
   sysdate,
   to_char(sysdate, 'hh24:mi:ss'),
   null,
   null,
   null
);
END;
/

ログオフのトリガーは次のとおりです。

create or replace trigger
   logoff_audit_trigger
BEFORE LOGOFF ON DATABASE
BEGIN
UPDATE
    stats$user_log
set

      logoff_day = sysdate,
      logoff_time = to_char(sysdate, 'hh24:mi:ss'),
      elapsed_minutes = round((logoff_day - logon_day)*1440,2)

  WHERE
   sys_context('USERENV','SESSIONID') = session_id;
END;
/

ユーザーがログアウトすると、elapse_minutes 列を除くすべてがキャプチャされ、null のままになります。

どこが間違っているのか誰か教えてください。ありがとう

4

2 に答える 2

0

更新を行う時点logoff_dayでは、式の右側で参照するsetはまだ null であるため、式は null と評価されます。

参照する列の値は更新前の値である必要があります。または、set句内で列が割り当てられている順序を変更すると、更新の動作が変わり、混乱を招く可能性があります。たとえば、古い値に基づいて列を設定する更新は、set salary = salary * 1.1特に問題になります。

sysdate代わりにもう一度参照できます。

  logoff_day = sysdate,
  logoff_time = to_char(sysdate, 'hh24:mi:ss'),
  elapsed_minutes = round((sysdate - logon_day)*1440,2)
于 2013-03-31T22:32:39.497 に答える
0

セッション監査が有効になっている場合、データベースはすでにこれを行っています。なぜ自分のためにそれを作成するのですか?結果については、dba_audit_session を確認してください。アクセスするには、データベース管理者やセキュリティ スタッフに相談する必要があるかもしれませんが、その価値があるかもしれません。

于 2013-04-01T10:24:09.997 に答える