A master trigger - sql

friends, I need your help,
I have a problem, I need to create a trigger that stores in a table all the interaction (access, insert, update, etc) that runs with the database; that saves who(user), when and what did (the query that was executed) in oracle.
Thanks in advance

You gave very few information on what you actually need, but you seem to be looking for the AUDIT functionality, that is available in Oracle 11g (that you tagged your question with).
From the docs :
Auditing is the monitoring and recording of selected user database actions. In standard auditing, you use initialization parameters and the AUDIT and NOAUDIT SQL statements to audit SQL statements, privileges, and schema objects, and network and multitier activities.
Check out this documentation, or this other one

Related

How to create sql transaction audit software without using fn_dblog or fn_dump_dblog directly on database

I am working on a sql transaction audit software
initial i am using fn_dblog on database to read sql transactions and write them in a file on regular time interval but then i find that it's risky to use fn_dblog on production database
so please suggest me any other alternative way to get data from production database
Note - I am already try to get sql transaction history from backup file(.bak) by reading transaction from it (using fn_dblog on my system not on database) but
that does not help me (because it not contains all transaction history)
fn_dblog() is an undocumented SQL Server function so you are wise to be careful using it.
Your question on how to audit transactions really depends on what you want to audit. Is it really every single transaction that occurs? Or, is it specific types of transactions like DDL and DML operations? There are a few options depending on the answer to this, yoru specific business case, etc.
Change Data Capture was introduced in 2008 and captures insert, update, and delete activity. For many cases, this is what folks want to edit. What user (usually from an application) edited data in the database.
DDL and DML Triggers can be created to fire when a specific event occurs. For DML this includes actions like INSERT, UPDATE, DELETE, etc. You can create the trigger to log the action after it occurs as an auditing feature. These types of triggers can lead to performance issues, so be sure to read up on them. I'd start with Aaron Bertrand's blog on them. DDL triggers depend on certain DDL events like creating and dropping a database, creating encryption, altering indexes, creating users, etc.
SQL Server Audit is a built in mechanism that create server audits, which can contain server audit specifications for server level events, and database audit specifications for database level events. Audited events can be written to the event logs or to audit files. Note a big difference from Change Data Capture is that it isn't stored in clean relational format like CDC is.
Change your application. This would be an application and database design change, but this method is commonly implemented. Essentially each time a change is made to a data row, instead of editing it, a new row is inserted with a timestamp and the user that made the change. This record becomes the "current truth" record and all other records area history of that record. SQL Server has methods to make this integrated using ROWVERSION and TEMPORAL TABLES
Use a paid option like Redgate, Solarwinds, etc...

Full SQL Statement History

I am facing a problem on a particular table in my database. The rows are being deleted without any reason (I have some procedures and triggers that modify the information inside the table but they are already tested).
So I need to see which DML statements are executed against the table.
I have already tried some methods, like using this query:
select SQL_FULLTEXT, FIRST_LOAD_TIME, ROWS_PROCESSED, PARSING_SCHEMA_NAME from v$sql;
filtering by the name of my table, or tried the SQL log.
Both methods don't show me the complete history of SQL executed (for example I can't see the statements executed by the procedures).
Can anyone give me some advice of where I can see ALL the DML executed in the database?
You're using a few terms that aren't defined within the context of Oracle Database, both 'sentence' and 'register.'
However.
If you want to see WHO is touching your data in a bad place, causing it to be deleted or changed, then you have 2 options.
Immediately, check your REDO logs. We have a package, dbms_logmnr, that will allow you to see what activity has been logged. Assuming that your tables weren't created with NOLOGGING clause, those UPDATEs and DELETEs should be recorded.
Tim has a nice article on this feature here.
The better solution going forward is AUDITING. You'll want to enable auditing in the database to record WHO is doing WHAT to your tables/data. This is included as part of the Enterprise Edition of the database. There is a performance hit, the more you decide to record, the more resources it will require. But it will probably be worth paying that price. And of course you'll have to manage the space required to maintain those logs.
Now, as to 'SQL Developer' and it's HISTORY feature. It ONLY records what you are executing in a SQL Worksheet. It won't see what others are doing. It can't help you here - unless this is a 1-man database, and you're only making changes with SQL Developer. Even then, it wouldn't be reliable as it has a limit, and only records changes done via the Worksheet.

Ensure that a SQL query is READ-only

What would be the best way to ensure that a SQL query won't alter the data of a database?
In my scenario, you don't have access to the database layer and can only do this logic on the application layer.
Would you recommend using a gem, a ruby custom script?
You can manage the permissions of the users so that they have access for reading the database but they don't have access to alter the database (i.e. not able to insert, update and delete). If you are using mysql, for instance, you can easily do this in phpmyadmin or equivalent tool.
Update based on your change. Even if you only have access through the application you are still connected to the database as a user who has or does not have privileges to update, delete, insert or select and as such the only way to ensure no such queries are executed is to alter that user's permissions.
A simple but far from foolproof method is to employ a blacklist of words that cannot be in the query, such as insert, update, etc.
Alternatively, you could use a parser on the sql query that will provide you with the necessary information to derive whether or not to allow the query.
I would take option 1 only as a last resort or if your checking needs are relatively simple.
On the database layer, make sure that the user the Rails app is accessing the database as only has the access that you desire, perhaps only SELECT.
Sequel has support for read only slave databases with a writable master database. Read-only slaves handle SELECT queries, other queries are done by the master database.
Maybe you can just setup master database as nil?
Another approach could be using hooks (before_save) to prevent writing to the database.

How to find the last time a table is queried in oracle

I want to get the information about when a table is queried in oracle.
Is there any log in oracle which shows the queries. I was looking around v$sqlarea and v$sqltext but, the system admin does not allow me to reach those tables.
In a default installation I know of no way to reliably get this info. You may be able to catch SQL Statements that were recently run in v$sql* views, but v$sql* views are transient in nature and are used to support normal operations of the database. Statements can age out so it is not a reliable way to audit.
What is a proper reliable way to get this info? Oracle Auditing. It contains the ability to record fine grained information about how your database objects are touched.
In this case you will want to investigate the AUDIT SELECT. After doing the basic config for auditing (usually done by a DBA) then SELECT auditing can be set up for specific tables like this:
AUDIT SELECT ON employees;
When a user SELECTS from employee, either directly or through a view, a record will be written to the audit trail (text file or SYS.AUD$ depending on configuration). The trail will have username, timestamp, table_name, and some other information to help you determine what the user was doing at the time.
Here is a 9i reference for auditing that gives an overview including info on AUDIT SELECT: http://download.oracle.com/docs/cd/B10500_01/server.920/a96524/c25audit.htm
Be aware that fine grained auditing can slow things down. Whatever you are auditing now has a new layer of activity that must be completed (writing to the audit trail). If you have a business need to know who sees what data that is understandable, but make sure to be aware of the performance implications.

How to monitor and log all the SQL insert commands

I am using Oracle SQL Dev 2.1.1.64
I work with application that uses oracle database for storage.
Is there any way in SQL Dev. to monitor and log all the insert commands that are "coming" from the web application into database? Can you tell me how to do that?
audit insert table by <web-application-user> by access
should get you started.
Be sure to set the parameters audit_trail and audit_file_dest as you need them.
After that, you find the operations either in sys.aud$ or in the directory specified by audit_file_dest.
There is also fine grained auditing into which you might take a look, but from your question, using fine grained auditing (FGA) would seem to be overkill.
You can write a trigger for the tables you want to monitor. If you are only interested on the insert queries coming from the Web Application, you can check on the trigger for some specific username/schema accessing the table, and use that username as your web application credentials.
Alternatively you can also use Oracle's AUDIT feature. It requires a little bit of Oracle Database Administration knowledge to implement though...
You could query v$SQL, but you would need to have the relevant GRANTS to enable you to do this.
For long running sessions you can also monitor progress using v$session_longops
hope this helps you.
Create a trigger that writes to a journaling table whenever a change of data in the table happens (insert, update, delete).
Before delete, after insert, after update triggers are what you want.
It won't specifically log only the web application, but if you log the user making the change you will be able to filter on that when viewing the data.