使用Oracle触发器填充表

cyej8jka  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(126)

我正试图跟踪一个失败的用户登录到Oracle数据库进行监视的目的。计划是在数据库登录时使用触发器。表已创建,触发器已成功与表关联。表CREATE语句和TRIGGER成功。当检查表值时,oracle不返回任何记录。我怎么能做到这一点?

--create table

CREATE TABLE myschema.errors(
    user_name VARCHAR2(30) NOT NULL ENABLE,
        error_code VARCHAR2(50) NOT NULL ENABLE,
            error_message VARCHAR2(50) NOT NULL ENABLE,
               error_time timestamp)
                 TABLESPACE "USERS";

--create application context
CREATE CONTEXT myschema6_ctx USING myschema.myschema6_pkg; 

--create package body
CREATE OR REPLACE PACKAGE BODY myschema.myschema6_pkg 
    IS 
        c_context CONSTANT VARCHAR2(30) := 'myschema6_ctx';
    username  VARCHAR2(30);
    My_USER  VARCHAR2(30);
 
            PROCEDURE set_contexts IS 
            BEGIN 
            SELECT SYS_CONTEXT ('USERENV', 'SESSION_USER') into username FROM DUAL;
            SELECT SYS_CONTEXT ('USERENV', 'OS_USER') into My_USER FROM DUAL;
            DBMS_SESSION.SET_CONTEXT ( c_context, username, My_USER); 
    END; 
            END myschema6_pkg; 
                / 

--create trigger
CREATE OR REPLACE TRIGGER myschema6_ctx_trig AFTER LOGON ON DATABASE
    DECLARE 
    My_USER VARCHAR2(30);
        v_code VARCHAR2(30);
        v_errm VARCHAR2(30);
    BEGIN
        myschema.myschema6_pkg.set_contexts;
        SELECT SYS_CONTEXT ('USERENV', 'OS_USER') into My_USER FROM DUAL;
            EXCEPTION
                WHEN OTHERS THEN
                   v_code := SQLCODE;
                   v_errm := SUBSTR(SQLERRM, 1 , 64);

                   -- to insert information about errors.
                INSERT INTO myschema.errors(user_name,error_code,error_message,error_time)
                VALUES(My_USER,v_code,v_errm, SYSTIMESTAMP);
    END;
/
zvms9eto

zvms9eto1#

不能使用“AFTER LOGON ON DATABASE“触发器捕获登录失败。登录失败永远不会成功登录,因此永远不会执行此类触发器。
但是,您可以使用“AFTER SERVERERROR ON DATABASE“触发器捕获登录失败,每当向调用客户端引发ORA异常时,就会触发该触发器,这将包括登录时的任何错误消息(无效密码、帐户锁定等)。在触发器中,查看server_error(1)并主要查找2800010171005的值(它们是正的,而不是负的)。请注意,对于登录失败,v$session中的USERNAME将是NULL。您必须通过查看SYS_CONTEXT('USERENV','AUTHENTICATED_IDENTITY')来获取预期的用户名。
此外,不需要使用包或设置上下文。您可以使用标准的SYS_CONTEXT('USERENV',...)调用或通过使用SID点击像v$session这样的V$视图来访问触发器中所需的所有内容。最后,在任何用于写入日志的触发器中,您都希望使其成为一个自治事务并包含一个COMMIT:

DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  INSERT ...

  COMMIT;
END;

但是,为了简单起见,我建议您首先尝试Oracle的标准登录审计。如果它被启用,只需查询DBA_AUDIT_TRAIL登录失败:

SELECT *
  FROM dba_audit_trail
 WHERE action_name = 'LOGON'
   AND returncode <> 0

或者,如果使用统一审核:

SELECT *
  FROM unified_audit_trail
 WHERE action_name = 'LOGON'
   AND return_code <> 0

只有当您确实需要审计无法提供的有关客户端的丰富信息时,才使用系统错误触发器。

相关问题