【发布时间】:2009-01-29 18:00:37
【问题描述】:
有没有办法将oracle 10g中所有失败的sql语句记录到表或文件中?
失败是指格式错误的 sql 语句或没有表或对象权限的 sql 语句。
【问题讨论】:
有没有办法将oracle 10g中所有失败的sql语句记录到表或文件中?
失败是指格式错误的 sql 语句或没有表或对象权限的 sql 语句。
【问题讨论】:
您可能想使用如下审计:
审核选择表、插入表、删除表、执行过程 通过访问 当不成功时;
By ACCESS 是针对每条语句的(这似乎是你想要的)。按 SESSION 将在每个会话中记录一条记录(高容量环境)。
Oracle 内置审计的开销比触发器少。其他答案包含的触发器允许您记录所需的确切信息。审计也只会捕获对现有对象的命中。如果有人在不存在的表(拼写错误或诸如此类)上进行选择,审计将无法捕捉到它。上面的触发器会。
安全指南中的更多信息:http://download.oracle.com/docs/cd/B19306_01/network.102/b14266/auditing.htm#i1011984
【讨论】:
没有像 Demge 的回答那样点击系统视图,而是有一个 ora_sql_txt 函数可以给出相关的语句。
create or replace TRIGGER log_err after servererror on schema
DECLARE
v_stack VARCHAR2(2000) := substr(dbms_utility.format_error_stack,1,2000);
v_back VARCHAR2(2000);-- := substr(dbms_utility.format_error_backtrace,1,2000);
v_num NUMBER;
v_sql_text ora_name_list_t;
procedure track(p_text in varchar2) is
begin
insert into .... values (p_text);
end;
begin
v_stack := translate(v_stack,'''','"');
track(v_stack);
v_back := translate(v_back,'''','"');
if v_back is not null then track(v_back); end if;
v_num := ora_sql_txt(v_sql_text);
BEGIN
FOR i IN 1..v_num LOOP
track(to_char(i,'0000')||':'||v_sql_text(i));
END LOOP;
EXCEPTION
WHEN VALUE_ERROR THEN NULL;
END;
end;
在我自己的环境中,我实际上将“TRACK”作为使用自主事务的单独过程,而不是上面的块。
create or replace procedure track (p_text IN VARCHAR2) IS
PRAGMA AUTONOMOUS_TRANSACTION;
cursor c_user is
select sys_context('USERENV','CLIENT_INFO') client_info,
sys_context('USERENV','CURRENT_SCHEMA') curr_schema,
sys_context('USERENV','CURRENT_USER') curr_user,
sys_context('USERENV','DB_NAME') db_name,
sys_context('USERENV','HOST') host,
sys_context('USERENV','IP_ADDRESS') ip,
sys_context('USERENV','OS_USER') osuser,
sys_context('USERENV','SESSIONID') sessid,
sys_context('USERENV','SESSION_USER') sess_user,
sys_context('USERENV','TERMINAL') terminal
from dual;
user_rec c_user%rowtype;
v_mod VARCHAR2(48);
v_act VARCHAR2(32);
v_cli_info varchar2(64);
begin
open c_user;
fetch c_user into user_rec;
close c_user;
DBMS_APPLICATION_INFO.READ_MODULE (v_mod, v_act);
--DBMS_APPLICATION_INFO.READ_CLIENT_INFO(v_cli_info);
insert into track_detail
(id, track_time, detail, client_info, curr_schema, curr_user, db_name,
host, ip, osuser, sessid, sess_user, terminal, module, action)
values (track_seq.nextval, systimestamp, p_text,
user_rec.client_info, user_rec.curr_schema, user_rec.curr_user,
user_rec.db_name, user_rec.host, user_rec.ip,
user_rec.osuser, user_rec.sessid, user_rec.sess_user,
user_rec.terminal, v_mod, v_act);
commit;
end;
【讨论】:
您可以使用系统触发器来执行此操作。
我直接从http://www.psoug.org/reference/system_trigger.html复制了这段代码。
CREATE TABLE servererror_log (
error_datetime TIMESTAMP,
error_user VARCHAR2(30),
db_name VARCHAR2(9),
error_stack VARCHAR2(2000),
captured_sql VARCHAR2(1000));
CREATE OR REPLACE TRIGGER log_server_errors
AFTER SERVERERROR
ON DATABASE
DECLARE
captured_sql VARCHAR2(1000);
BEGIN
SELECT q.sql_text
INTO captured_sql
FROM gv$sql q, gv$sql_cursor c, gv$session s
WHERE s.audsid = audsid
AND s.prev_sql_addr = q.address
AND q.address = c.parent_handle;
INSERT INTO servererror_log
(error_datetime, error_user, db_name,
error_stack, captured_sql)
VALUES
(systimestamp, sys.login_user, sys.database_name,
dbms_utility.format_error_stack, captured_sql);
END log_server_errors;
/
【讨论】:
ORA-04045: errors during recompilation/revalidation of RX_OAUTH.LOG_SERVER_ERRORS ORA-01031: insufficient privileges 收到以下错误,并且没有记录任何内容。即使对于系统用户