No audit results - oracle

I have been testing audit area in Oracle 11g. Unfortunately, after I go through below-described steps, I get no results in audit tables. I am connected to the database as store. Why is that?
GRANT AUDIT SYSTEM TO store;
GRANT AUDIT ANY TO store;
AUDIT CREATE ANY TABLE BY store;
CREATE TABLE test_mj_aud(
id INTEGER);
INSERT INTO test_mj_aud
VALUES (1);
COMMIT;
SELECT * FROM test_mj_aud;
SELECT * FROM user_audit_trail; --no results
SELECT * FROM db_audit_trail; --no results

Related

How to select all DML statement done to a table

With this query, I can see which table where modified last hour.
select * from ALL_TAB_MODIFICATIONS where timestamp> sysdate-1/24
Now I want to know what has been insert, updates, deletes in a table. And if possible with the user id.
How do I do that?
I've tried to use audit.
https://www.ibm.com/docs/en/svgaa?topic=c-enabling-auditing-oracle-resource
in sqlplus
SHOW PARAMETER AUDIT_TRAIL
DB --OK
AUDIT ALL BY SEV BY ACCESS
audit succeeded
I've tried to see the content of all the audit table (SELECT view_name FROM dba_views WHERE view_name LIKE 'DBA%AUDIT%';)
for instance :
select * from dba_audit_exists;
but they are empty

Materialized view fast refresh - insert and delete when updating base table

Hello fellow Stackoverflowers,
TLDR: Are MVIEWs using UPDATE or DELETE + INSERT during refresh?
some time ago I ran into an obscure thing when I was fiddling whit materialized views in Oracle. Here is my example:
2 base tables
MVIEW logs for both tables
PKs for both tables
MVIEW created as a join of these base tables
PK for MVIEW
Here is an example code:
-- ========================= DDL section =========================
/* drop tables */
drop table tko_mview_test_tb;
drop table tko_mview_test2_tb;
/* drop mview */
drop materialized view tko_mview_test_mv;
/* create tables */
create table tko_mview_test_tb as
select 1111 as id, 'test' as code, 'hello world' as data, sysdate as timestamp from dual
union
select 2222, 'test2' as code, 'foo bar', sysdate - 1 from dual;
create table tko_mview_test2_tb as
select 1000 as id, 'test' as fk, 'some string' as data, sysdate as timestamp from dual;
/* create table PKs */
alter table tko_mview_test_tb
add constraint mview_test_pk
primary key (id);
alter table tko_mview_test2_tb
add constraint mview_test2_pk
primary key (id);
/* create mview logs */
create materialized view log
on tko_mview_test_tb
with rowid, (data);
create materialized view log
on tko_mview_test2_tb
with rowid, (data);
/* create mview */
create materialized view tko_mview_test_mv
refresh fast on commit
as select a.code
, a.data
, b.data as data_b
, a.rowid as rowid_a
, b.rowid as rowid_b
from tko_mview_test_tb a
join tko_mview_test2_tb b on b.fk = a.code;
/* create mview PK */
alter table tko_mview_test_mv
add constraint mview_test3_pk
primary key (code);
According to dbms_mview.explain_mview my MVIEW if capable of fast refresh.
Well in this particular case (not in example here) the MVIEW is referenced by an FK from some other table. Because of that, I found out, that when I do a change in one of these base tables and the refresh of MVIEW is triggered I got an error message:
ORA-12048: error encountered while refreshing materialized view "ABC"
ORA-02292: integrity constraint (ABC_FK) violated
I was like What the hell??. So I started digging - I created a trigger on that MVIEW. Something like this:
/* create trigger on MVIEW */
create or replace trigger tko_test_mview_trg
after insert or update or delete
on tko_mview_test_mv
referencing old as o new as n
for each row
declare
begin
if updating then
dbms_output.put_line('update');
elsif inserting then
dbms_output.put_line('insert');
elsif deleting then
dbms_output.put_line('delete');
end if;
end tko_test_mview_trg;
/
So I was able to see what is happening. According to my trigger, every time I do UPDATE in the base table (not INSERT nor DELETE) there is actually DELETE and INSERT operation on MVIEW table.
update tko_mview_test2_tb
set data = 'some sting'
where id = 1000;
commit;
Output
delete
insert
Is this correct way how refresh of MVIEW works? There is no updates on MVIEW table when refreshing MVIEW?
Regards,
Tom
We have seen the same behavior after upgrading from oracle 12.1 to oracle 19.x
Newly created mviews seems to behave the same, a delete/insert during the refresh instead of the 'expected' update. Not sure if it is bad or wrong.....but it can be 'fixed'.
Apply patch 30781970 (don't forget _fix_control) and recreate the mview.....
Reference: Bug 30781970 - MVIEW REFRESH IS FAILING WITH ORA-1 ERROR WITH TRIGGER PRESENT ON MVIEW (Doc ID 30781970.8)

Why dml error logging ignored in remote db

I have that table - DIM_BP in 2 databases, with the same structure and data.
Those tables have PK on some columns.
There is an insert statement with dml error logging for catch the errors during the insert.
When I run the insert command from DB1 into DB2 with dblink - I got an error of PK unique constraint and the statement fail (dml error logging ignored).
But when I run in it from DB1 into DB1 (local) - there is no error.. and the error table filled with the errors..
example:
-- truncate table error table
truncate table DWH.ERR$_DWH_CONV;
table DWH.ERR$_DWH_CONV truncated.
-- truncate table in local DB
truncate table DWH.DIM_BP;
table DWH.DIM_BP truncated.
-- (log in to the remote server and) truncate the table
truncate table DWH.DIM_BP;
table DWH.DIM_BP truncated.
-- log to the local DB again
-- first insert into the remote
-- finisehd OK and commited
INSERT /*+ monitor */ INTO DWH.DIM_BP#DWH_DEV
SELECT * FROM ...
LOG ERRORS INTO DWH.ERR$_DWH_CONV ('DWH.DIM_BP#DWH_DEV.2019-04-16 16:05:58') REJECT LIMIT UNLIMITED;
130,091 rows inserted.
commit;
-- first insert into the local
-- finisehd OK and commited
INSERT /*+ monitor */ INTO DWH.DIM_BP
SELECT * FROM ...
LOG ERRORS INTO DWH.ERR$_DWH_CONV ('DWH.DIM_BP#DWH_DEV.2019-04-16 16:05:58') REJECT LIMIT UNLIMITED;
130,091 rows inserted.
commit;
-- run the same insert again into the local table(130091)
INSERT /*+ monitor */ INTO DWH.DIM_BP
SELECT * FROM ...
LOG ERRORS INTO DWH.ERR$_DWH_CONV ('DWH.DIM_BP#DWH_DEV.2019-04-16 16:05:58') REJECT LIMIT UNLIMITED;
0 rows inserted.
COMMIT;
select count(*) from dwh.ERR$_DWH_CONV;
result: 130091
-- run the same insert again into the REMOTE table(130091)
-- RAISED AN ERROR
INSERT /*+ monitor */ INTO DWH.DIM_BP#DWH_DEV
SELECT * FROM ...
LOG ERRORS INTO DWH.ERR$_DWH_CONV ('DWH.DIM_BP#DWH_DEV.2019-04-16 16:05:58') REJECT LIMIT UNLIMITED;
SQL Error: ORA-00001: unique constraint - DWH.DIM_BP_PK
-- check again the error table
select count(*) from dwh.ERR$_DWH_CONV;
result: 130091 (no change)
this is the constraint:
CONSTRAINT "DIM_BP_PK" PRIMARY KEY... ENABLED;

Incorrect output while using dictionary tables inside Trigger

I am using ALL_TABLES/ALL_TAB_COLUMNS to get count of tables in my schema (EDW_SRC) and another schema(EDW_STG). I get correct counts when i run the query in my sql developer as shown below. But if i put the same query inside a trigger, i get wrong count for other schema(EDW_STG).
Please refer below code:
(This is just a sample code to replicate the issue, not my business requirement. I am referring ALL_TAB_COLUMNS in my actual code to get the number of columns in a particular table in different schema, for which i have Select access.)
select user from dual;
USER
-----
EDW_SRC
DROP TABLE ABC;
Table ABC dropped.
CREATE TABLE ABC(ID NUMBER);
Table ABC created.
select count(1) EDW_STG_CNT
from all_tables
where owner='EDW_STG';--Different Schema
EDW_STG_CNT
----------
101
select count(1) EDW_SRC_CNT
from all_tables
where owner='EDW_SRC';--My Schema
EDW_SRC_CNT
------------
1554
create or replace trigger trig_test_dml_abc
before insert on abc
DECLARE
V_STG_CNT number :=NULL;
V_SRC_CNT number :=NULL;
begin
DBMS_OUTPUT.PUT_LINE('***** TRIGGER OUTPUT *****');
select count(1) into V_SRC_CNT from all_tables
where owner='EDW_SRC'; --My Schema
DBMS_OUTPUT.PUT_LINE('My Schema EDW_SRC_CNT :'||V_SRC_CNT);
select count(1) into V_STG_CNT from all_tables
where owner='EDW_STG'; --Different Schema
DBMS_OUTPUT.PUT_LINE('Different Schema EDW_STG_CNT :'||V_STG_CNT);
end;
Trigger TRIG_TEST_DML_ABC compiled
INSERT INTO ABC VALUES (2);
1 row inserted.
***** TRIGGER OUTPUT *****
My Schema EDW_SRC_CNT :1554
Different Schema EDW_STG_CNT :2
The Different Schema count should be 101. Why is it coming as 2.
Oracle Version:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
Thanks
K

SELECT AS OF a version before column drop

1/ Does FLASHBACK and SELECT AS OF/ VERSION BETWEEN use the same source of history to fall back to ? This question is related to the second question.
2/ I am aware that FLASHBACK cannot go back before a DDL change.
My question is for SELECT AS OF, would it be able to select something before a DDL change.
Take for example
CREATE TABLE T
(col1 NUMBER, col2 NUMBER)
INSERT INTO T(col1, col2) VALUES('1', '1')
INSERT INTO T(col1, col2) VALUES('2', '2')
COMMIT;
SLEEP(15)
ALTER TABLE T DROP COLUMN col2;
SELECT * FROM T
AS OF SYSTIMESTAMP - INTERVAL '10' SECOND;
Would the select return 2 columns or 1 ?
Pardon me I do not have a database at hand to test.
Any DDL that alter the structure of a table invalidates any existing undo data for the table. So you will get the error 'ORA-01466' unable to read data - table definition has changed.
Here is a simple test
CREATE TABLE T
(col1 NUMBER, col2 NUMBER);
INSERT INTO T(col1, col2) VALUES('1', '1');
INSERT INTO T(col1, col2) VALUES('2', '2');
COMMIT;
SLEEP(15)
ALTER TABLE T DROP COLUMN col2;
SELECT * FROM T
AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '60' SECOND);
ERRROR ORA-01466 upon executing the above select statement.
However DDL operations that alter the storage attributes of a table do no invalidate undo data so that you can still use flashback query.
1) FLASHBACK TABLE and SELECT .. AS OF use the same source, UNDO. There is also FLASHBACK DATABASE - although it uses the same mechanism it uses a separate source, flashback logs that must be optionally configured.
2) Flashback table and flashback queries can go back before a DDL change if you enable a flashback archive.
To use that feature, add a few statements to the sample code:
CREATE FLASHBACK ARCHIVE my_flashback_archive TABLESPACE users RETENTION 10 YEAR;
...
ALTER TABLE t FLASHBACK ARCHIVE my_flashback_archive;
Now this statement will return 1 column:
SELECT * FROM T;
And this statement will return 2 columns:
SELECT * FROM T AS OF SYSTIMESTAMP - INTERVAL '10' SECOND;

Resources