I have a scenario to rollBack any delete on table and also log whatever was delete candidate
-- Original table
CREATE TABLE dbo.tblDomain(
DoaminId INT NULL,
Description varchar(50) NULL
);
-- Table Population
insert into dbo.tblDomain
select 1,'Desc1'
union All
select 2,'Desc2'
union All
select 3,'Desc3'
union All
select 4,'Desc4';
/*---============= Creating table to store deleted records.
table structure is same as dbo.tblDomain except last 2 columns
FromDeleteUser varchar (100) –- who initiated delete
DeleteDate datetime -- datatime of delete transaction
*/
CREATE TABLE dbo.tblDomain_tmpTrg(
DoaminId INT NULL,
Description varchar(500) NULL,
FromDeleteUser varchar (100),
DeleteDate datetime.
FromDeleteUser varchar (100),
DeleteDate datetime
);
--===== Create trigger to fire on primary table delete
CREATE TRIGGER trg_tblDomain_DeleteLog
ON dbo.tblDomain
AFTER DELETE
AS
BEGIN
SET NOCOUNT ON;
-- use table variable to store data to be logged before rolling back transaction
declare @trg table ( DoaminId INT NULL,
Description varchar(500) NULL,
FromDeleteUser varchar (100),
DeleteDate datetime
)
insert @trg select * from deleted
ROLLBACK
-- transacion rolled-back, but data is still available in @trg
-- log it into proper table
insert dbo.tblDomain_tmpTrg
select * , suser_sname(), getutcdate()
from @trg
-- re-raise the error to make it clear!
raiserror ('Delete from table dbo.dbo.tblDomain is not allowed, your action is logged!',16,1)
END
GO
--===================== Verification
--SELECT * FROM dbo.tblDomain;
--DELETE FROM dbo.tblDomain ;
--SELECT * FROM dbo.tblDomain_tmpTrg;
--=== Drop objects
--DROP TRIGGER trg_tblDomain_DeleteLog;
--DROP dbo.tblDomain_tmpTrg;
Tuesday, January 29, 2013
Thursday, January 24, 2013
SQL Server Trigger - Insert the deleted record into another table with deletetime
SQL Server Trigger - Insert the deleted record into another table with deletetime
/*
Author: Tanveer Haider Baig
Description : Trigger to fire after delete on table and populate deleted records to another table with timestamp
*/
--Create Primary table
CREATE TABLE tblTrgTest1
(
id INT,
NAME VARCHAR(10)
);
--=== Populating Table
INSERT INTO tblTrgTest1
SELECT 1,'a'
UNION ALL
SELECT 2,'b'
UNION ALL
SELECT 3,'c'
UNION ALL
SELECT 4,'d'
UNION ALL
SELECT 5,'e';
--=== Retrivening Results
SELECT * FROM tblTrgTest1;
--===== Create secondary table to host deleted values
CREATE TABLE tblTrgTest2
(
id INT,
NAME VARCHAR(10),
delDate DATETIME
);
--===== Create trigger to fire on primary table delete
CREATE TRIGGER trgTableDeleteLog
ON tblTrgTest1
AFTER DELETE
AS
INSERT INTO tblTrgTest2
SELECT * ,GETDATE()
FROM DELETED;
---===== delete records to test trigger
DELETE FROM tblTrgTest1 WHERE id IN (1,2);
DELETE FROM tblTrgTest1 WHERE id IN (3,5);
--Verify deleted records come to secondry table with timestamp
SELECT * FROM tblTrgTest2;
--Verify delete was successfull on primary
SELECT * FROM tblTrgTest1;
--=== Drop objects
DROP TRIGGER trgTableDeleteLog;
DROP TABLE tblTrgTest1;
DROP TABLE tblTrgTest2;
/*
Author: Tanveer Haider Baig
Description : Trigger to fire after delete on table and populate deleted records to another table with timestamp
*/
--Create Primary table
CREATE TABLE tblTrgTest1
(
id INT,
NAME VARCHAR(10)
);
--=== Populating Table
INSERT INTO tblTrgTest1
SELECT 1,'a'
UNION ALL
SELECT 2,'b'
UNION ALL
SELECT 3,'c'
UNION ALL
SELECT 4,'d'
UNION ALL
SELECT 5,'e';
--=== Retrivening Results
SELECT * FROM tblTrgTest1;
--===== Create secondary table to host deleted values
CREATE TABLE tblTrgTest2
(
id INT,
NAME VARCHAR(10),
delDate DATETIME
);
--===== Create trigger to fire on primary table delete
CREATE TRIGGER trgTableDeleteLog
ON tblTrgTest1
AFTER DELETE
AS
INSERT INTO tblTrgTest2
SELECT * ,GETDATE()
FROM DELETED;
---===== delete records to test trigger
DELETE FROM tblTrgTest1 WHERE id IN (1,2);
DELETE FROM tblTrgTest1 WHERE id IN (3,5);
--Verify deleted records come to secondry table with timestamp
SELECT * FROM tblTrgTest2;
--Verify delete was successfull on primary
SELECT * FROM tblTrgTest1;
--=== Drop objects
DROP TRIGGER trgTableDeleteLog;
DROP TABLE tblTrgTest1;
DROP TABLE tblTrgTest2;
Friday, January 18, 2013
Oracle 10g User Auditing
I start receiving oracle alerts for excessive sessions. So I decided to audit user to find source IP that request for session.
view audit status
SQL> SHOW PARAMETER AUDIT
audit_trail options:
AUDIT_TRAIL = { none | os | db | db,extended | xml | xml,extended }
The following list provides a description of each setting:
none or false - Auditing is disabled.
db or true - Auditing is enabled, with all audit records stored in the database audit trial (SYS.AUD$).
db,extended - As db, but the SQL_BIND and SQL_TEXT columns are also populated.
xml- Auditing is enabled, with all audit records stored as XML format OS files.
xml,extended - As xml, but the SQL_BIND and SQL_TEXT columns are also populated.
os- Auditing is enabled, with all audit records directed to the operating system's audit trail
SQL> ALTER SYSTEM SET audit_trail=db SCOPE=SPFILE;
SQL> SHUTDOWN
SQL> STARTUP
--Auditing only single user connection
CONNECT sys/password AS SYSDBA
SQL> audit connect by MyUser;
--View audit info
SQL> select userhost, terminal, timestamp, action_name,comment_text from dba_audit_session where username=’MYUser’;
comment_text holds IP address.
You can format your results with the following query.
select count(*),action_name,audi.username,substr(audi.s1,1,instr(audi.s1,')')-1) IP from
(
select username,action_name,substr(comment_text,instr(comment_text,'HOST=')+5,100) s1
from dba_audit_trail
where username='MYUSER'
--and action_name ='LOGON'
--and action_name in ('LOGON','LOGOFF')
)audi
group by audi.username,substr(audi.s1,1,instr(audi.s1,')')-1),action_name
order by 1 desc ;
-- Fetch Audit related views in database
SELECT view_name
FROM dba_views
WHERE view_name LIKE 'DBA%AUDIT%'
ORDER BY view_name;
VIEW_NAME
------------------------------
DBA_AUDIT_EXISTS
DBA_AUDIT_OBJECT
DBA_AUDIT_POLICIES
DBA_AUDIT_POLICY_COLUMNS
DBA_AUDIT_SESSION
DBA_AUDIT_STATEMENT
DBA_AUDIT_TRAIL
DBA_COMMON_AUDIT_TRAIL
DBA_FGA_AUDIT_TRAIL
DBA_OBJ_AUDIT_OPTS
DBA_PRIV_AUDIT_OPTS
DBA_REPAUDIT_ATTRIBUTE
DBA_REPAUDIT_COLUMN
DBA_STMT_AUDIT_OPTS
14 rows selected.
SQL>
The three main views are shown below.
DBA_AUDIT_TRAIL - Standard auditing only (from AUD$).
DBA_FGA_AUDIT_TRAIL - Fine-grained auditing only (from FGA_LOG$).
DBA_COMMON_AUDIT_TRAIL - Both standard and fine-grained auditing.
view audit status
SQL> SHOW PARAMETER AUDIT
audit_trail options:
AUDIT_TRAIL = { none | os | db | db,extended | xml | xml,extended }
The following list provides a description of each setting:
none or false - Auditing is disabled.
db or true - Auditing is enabled, with all audit records stored in the database audit trial (SYS.AUD$).
db,extended - As db, but the SQL_BIND and SQL_TEXT columns are also populated.
xml- Auditing is enabled, with all audit records stored as XML format OS files.
xml,extended - As xml, but the SQL_BIND and SQL_TEXT columns are also populated.
os- Auditing is enabled, with all audit records directed to the operating system's audit trail
SQL> ALTER SYSTEM SET audit_trail=db SCOPE=SPFILE;
SQL> SHUTDOWN
SQL> STARTUP
--Auditing only single user connection
CONNECT sys/password AS SYSDBA
SQL> audit connect by MyUser;
--View audit info
SQL> select userhost, terminal, timestamp, action_name,comment_text from dba_audit_session where username=’MYUser’;
comment_text holds IP address.
You can format your results with the following query.
select count(*),action_name,audi.username,substr(audi.s1,1,instr(audi.s1,')')-1) IP from
(
select username,action_name,substr(comment_text,instr(comment_text,'HOST=')+5,100) s1
from dba_audit_trail
where username='MYUSER'
--and action_name ='LOGON'
--and action_name in ('LOGON','LOGOFF')
)audi
group by audi.username,substr(audi.s1,1,instr(audi.s1,')')-1),action_name
order by 1 desc ;
-- Fetch Audit related views in database
SELECT view_name
FROM dba_views
WHERE view_name LIKE 'DBA%AUDIT%'
ORDER BY view_name;
VIEW_NAME
------------------------------
DBA_AUDIT_EXISTS
DBA_AUDIT_OBJECT
DBA_AUDIT_POLICIES
DBA_AUDIT_POLICY_COLUMNS
DBA_AUDIT_SESSION
DBA_AUDIT_STATEMENT
DBA_AUDIT_TRAIL
DBA_COMMON_AUDIT_TRAIL
DBA_FGA_AUDIT_TRAIL
DBA_OBJ_AUDIT_OPTS
DBA_PRIV_AUDIT_OPTS
DBA_REPAUDIT_ATTRIBUTE
DBA_REPAUDIT_COLUMN
DBA_STMT_AUDIT_OPTS
14 rows selected.
SQL>
The three main views are shown below.
DBA_AUDIT_TRAIL - Standard auditing only (from AUD$).
DBA_FGA_AUDIT_TRAIL - Fine-grained auditing only (from FGA_LOG$).
DBA_COMMON_AUDIT_TRAIL - Both standard and fine-grained auditing.
Oracle 10g user login Audit
you can audit user login or logoff request with triggers as well.
following needed
- Table that will hold trigger output
- Login trigger (in sys schema)
- Logoff trigger (in sys schema)
--------------------------------------------------------
-- DDL for Trigger output table
--------------------------------------------------------
CREATE TABLE "Schema"."TBLUSERCONNECTIONAUDIT"
( "DATE_CON" DATE,
"OSUSER" VARCHAR2(100 BYTE),
"PROGRAM" VARCHAR2(100 BYTE),
"MACHINE" VARCHAR2(100 BYTE),
"IP" VARCHAR2(100 BYTE),
"ACTION" VARCHAR2(30 BYTE)
)
( "DATE_CON" DATE,
"OSUSER" VARCHAR2(100 BYTE),
"PROGRAM" VARCHAR2(100 BYTE),
"MACHINE" VARCHAR2(100 BYTE),
"IP" VARCHAR2(100 BYTE),
"ACTION" VARCHAR2(30 BYTE)
)
--------------------------------------------------------
-- DDL for Trigger TRG_LOGON_AUDIT
--------------------------------------------------------
CREATE OR REPLACE TRIGGER "SYS"."TRG_LOGON_AUDIT"
AFTER LOGON ON DATABASE
DECLARE
v_prog SYS.v_$session.program%TYPE;
v_owner SYS.v_$session.username%TYPE;
v_osuser SYS.v_$session.osuser%TYPE;
v_machine SYS.v_$session.machine%TYPE;
v_ip VARCHAR2 (20);
BEGIN
-- Change user name as required
IF sys_context('USERENV','BG_JOB_ID') is null and user = 'USERNAME' THEN
SELECT program, username, osuser, machine,
SYS_CONTEXT ('USERENV', 'IP_ADDRESS')
INTO v_prog, v_owner, v_osuser, v_machine,
v_ip
FROM SYS.v_$session
WHERE audsid = USERENV ('SESSIONID')
AND audsid != 0
AND ROWNUM = 1;
IF UPPER (v_prog) NOT LIKE '%PL%SQL%'
THEN
insert into sanmar.tblUserConnectionAudit
(DATE_CON,
osuser, program, machine, ip,action
)
VALUES (SYSDATE,
v_osuser, v_prog, v_machine, v_ip,'LOGON'
);
ELSE
NULL; -- Logging the error
END IF;
END IF;
EXCEPTION
WHEN OTHERS
THEN
--* Logging the error
RAISE;
END;
/
ALTER TRIGGER "SYS"."TRG_LOGON_AUDIT" ENABLE;
--------------------------------------------------------
-- DDL for Trigger TRG_LOGOFF_AUDIT
--------------------------------------------------------
CREATE OR REPLACE TRIGGER "SYS"."TRG_LOGOFF_AUDIT"
Before LOGOFF ON DATABASE
DECLARE
v_prog SYS.v_$session.program%TYPE;
v_owner SYS.v_$session.username%TYPE;
v_osuser SYS.v_$session.osuser%TYPE;
v_machine SYS.v_$session.machine%TYPE;
v_ip VARCHAR2 (20);
BEGIN
-- Change user name as required
IF sys_context('USERENV','BG_JOB_ID') is null and user = 'USERNAME' THEN
SELECT program, username, osuser, machine,
SYS_CONTEXT ('USERENV', 'IP_ADDRESS')
INTO v_prog, v_owner, v_osuser, v_machine,
v_ip
FROM SYS.v_$session
WHERE audsid = USERENV ('SESSIONID')
AND audsid != 0
AND ROWNUM = 1;
IF UPPER (v_prog) NOT LIKE '%PL%SQL%'
THEN
insert into sanmar.tblUserConnectionAudit
(DATE_CON,
osuser, program, machine, ip,action
)
VALUES (SYSDATE,
v_osuser, v_prog, v_machine, v_ip,'LOGOFF'
);
ELSE
NULL; -- Logging the error
END IF;
END IF;
EXCEPTION
WHEN OTHERS
THEN
--* Logging the error
RAISE;
END;
/
ALTER TRIGGER "SYS"."TRG_LOGOFF_AUDIT" ENABLE;
Auto Start Oracle on Linux
Create the file /etc/init.d/dbora like this :
#!/bin/bash
#
# chkconfig: 35 99 10
# description: Starts and stops Oracle processes
#
ORA_HOME=/u01/app/oracle/product/11.2.0/dbhome_1 <--- to be changed
ORA_OWNER=oracle
case "$1" in
'start')
# Start the Oracle databases:
echo "Starting the Oracle databases"
su - $ORA_OWNER -c "$ORA_HOME/bin/dbstart $ORA_HOME"
# Start the TNS listener
# su - $ORA_OWNER -c "$ORA_HOME/bin/lsnrctl start"
touch /var/lock/subsys/dbora
;;
'stop')
# Stop the TNS listener
# su - $ORA_OWNER -c "$ORA_HOME/bin/lsnrctl stop"
# STOP the Oracle databases
echo "Shutting down the Oracle databases"
su - $ORA_OWNER -c "$ORA_HOME/bin/dbshut $ORA_HOME"
rm -f /var/lock/subsys/dbora
;;
*)
echo "Usage: dbora (start|stop)"
exit 1
esac
Then, issue the commands :
chmod 755 /etc/init.d/dbora
/sbin/chkconfig dbora on
Check also in the file /etc/oratab that the database(s) are configured to start automatically (you need a Y at the end of the line for each database :
ex :
APPSPROD:/u01/app/oracle/product/11.2.0/dbhome_1:Y
That's all !
Courtesy :Michel Berger
#!/bin/bash
#
# chkconfig: 35 99 10
# description: Starts and stops Oracle processes
#
ORA_HOME=/u01/app/oracle/product/11.2.0/dbhome_1 <--- to be changed
ORA_OWNER=oracle
case "$1" in
'start')
# Start the Oracle databases:
echo "Starting the Oracle databases"
su - $ORA_OWNER -c "$ORA_HOME/bin/dbstart $ORA_HOME"
# Start the TNS listener
# su - $ORA_OWNER -c "$ORA_HOME/bin/lsnrctl start"
touch /var/lock/subsys/dbora
;;
'stop')
# Stop the TNS listener
# su - $ORA_OWNER -c "$ORA_HOME/bin/lsnrctl stop"
# STOP the Oracle databases
echo "Shutting down the Oracle databases"
su - $ORA_OWNER -c "$ORA_HOME/bin/dbshut $ORA_HOME"
rm -f /var/lock/subsys/dbora
;;
*)
echo "Usage: dbora (start|stop)"
exit 1
esac
Then, issue the commands :
chmod 755 /etc/init.d/dbora
/sbin/chkconfig dbora on
Check also in the file /etc/oratab that the database(s) are configured to start automatically (you need a Y at the end of the line for each database :
ex :
APPSPROD:/u01/app/oracle/product/11.2.0/dbhome_1:Y
That's all !
Courtesy :Michel Berger
Subscribe to:
Posts (Atom)