View SQL History by User [Oracle] - oracle

I'm trying to find all (available) SQL history by user in our Oracle 11g database. I've tried using some view such as v$sql_monitor, v$sqlarea, and dba_hist_active_sess_history to try to get usernames, and their executed SQL statements (joined on SID and Serial #) but I'm not having any luck. Our senior DBA and DBE said they've done it before but just told me to look in sqlarea since that has the longest history of SQL held. I'm not having any luck with this. Is this possible to do in Oracle?
Edit: We use SQL Developer. I understand that TOAD may or may not have this feature built-in but I haven't been able to find anything that accomplishes this (other than view current sessions and current SQL) in SQL Developer.

You can try something like that if you have the proper licensing to query dba_hist_active_sess_history, you need a license for the diagnostic pack:
select trunc(hist.sample_time,'DD'),u.name,hist.sql_id,sql.sql_text
from dba_hist_active_sess_history hist,
dba_hist_sqltext sql,
user$ u
where hist.sql_id = sql.sql_id
and hist.user_id = u.user#;

I think the only way to fetch the exact SQL-Executions of a User (i think you mean Session?) is by enabeling Tracing.
I think this article (https://oracle-base.com/articles/misc/sql-trace-10046-trcsess-and-tkprof) gives you a good instruction how it is used.

Related

how to find the query used for creation of Temporary table in Oracle sql developer

I have created a temporary table in oracle sql developer but I forgot to save it and now I want to reuse the query but I don't remember the code used then. Is there a process to get query used creation of temp table?
You can use dbms_metadata.get_ddl()
select dbms_metadata.get_ddl('TABLE', 'YOUR_TABLE_NAME_HERE')
from dual;
The result is a CLOB with the complete DDL. You might need to adjust the display in SQL Developer to make the content of that value fully visible (I don't use SQL Developer, so I don't know if that is necessary and if so, what you would need to do)
Edit:
It seems SQL Developer can't display the result of this query properly unless you use the "Run Script" option. And with that you need to use a SET LONG 60000 (or some other big number) before you run it, to see the complete source code:

OracleDatareader seems to execute an update statement

I am using oracle client 11.2.0
Dll version 4.112.3.0
We have a page in our application where people can give a sql statement and retreive results. basically do an oracle command.executereader
Recently one of my team members gave an update statement as a test and it actually performed an update on a record!!!!
Anyone who has encountered this?
Regards
Sid.
It is a normal (albeit a bit unsettling) behavior. ExecuteReader is expected to execute the sql command provided as CommandText and build a DbDataReader that you use to loop over the results.
If the command doesn't return any row to read is not something that the reader should prevent in any case. And so it is not expected that it checks if your command is really a SELECT statement.
Think for example if you pass a stored procedure name or if you have multiple sql batch to execute. (INSERT followed by a SELECT)
I think that the biggest problem here is the fact that you allow an arbitrary sql command typed by your users to reach the database engine. A very big hole in security. You should, at least, execute some analysis on the query text before submitting the code to the database engine.
I agree with Steve. Your reader will execute any command, and might get a bit confused if it's not a select and doesn't return a result set.
To prevent people from modifying anything, create a new user, grant select only (no update, no delete, no insert) on your tables to that user (grant select on tablename to seconduser). Then, log in as seconduser, and, create synonyms for your tables (create synonym tablename for realowner.tablename). Have your application use the seconduser when connecting to the DB. This should prevent people from "hacking" your site. If you want to be of the safe side, grant no permissions but create session to the second user to prevent him from creating tables, dropping your views and similar stuff (I'd guess your executereader won't allow DDL, but test it to make sure).

Oracle DB audit trails

Someone (or something) actually updated a value in my table wrongly. I am trying to find out when the update happened. Unfortunately, there is no audit trigger being created for the said table.
Is there other ways or logs that I can check and verify what SQL statements were run at what time?
I had tried to look at v$sql table, but I don't think that table is capturing all the SQL statements being performed on the database. E.g. I specifically did an UPDATE statement, but it is not captured in the v$sql table.
Can I look at the redo.log? However, I do not know how to interpret this log.
Your only real option is logminer, which isn't for the faint of heart.
The documentation is here: http://docs.oracle.com/cd/B19306_01/server.102/b14215/logminer.htm
v$sql rows may get aged out after a while. Did you account for case sensitivity when looking in v$sql?
select * from v$sql where upper(sql_fulltext) like '%UPDATE%';

Oracle Execution Plan

I am using Oracle 11g and Toad for Oracle. How can I display execution plan for queries?
In Sql server management studio execution plan can be displayed as graphical format. Is there any functionality/tool like that on Toad for oracle?
CTRL-E
Make sure you've ended the query with a semi-colon (and the query above)
Edit:
You need to set-up the TOAD plan table for use. If you think it's already setup on your DB then you may just need to be granted access. Alternatively in my slightly older version of TOAD it's under:
Database --> Administer --> Server Side Objects Wizard. From here you can create the plan table(s) in a schema that you choose.
You should create the PLAN_TABLE using a script provided by Oracle
which is named UTLXPLAN.SQL and is located in one of the installation folders
on the database server.
Then, you should use the EXPLAIN PLAN statement for generating a plan for a SQL statement, like this:
EXPLAIN PLAN SET STATEMENT_ID = 'your_identifier_for_this_plan'
FOR
... your statement ... ;
Then, you can use either a select from PLAN_TABLE (usually using a hierarchical query) or the DBMS_XPLAN.DISPLAY_PLAN procedure to display the plan.
In the same folder where the UTLXPLAN.SQL file is located, there usually exist
examples of using this procedure.
Also, in SQL*PLUS you can use the SET AUTOTRACE feature.
For TOAD FOR ORACLE
this helped me How do I view the Explain Plan in Oracle Sql developer?, I just write what they did in sql developer and wrote in the toad editor and then execute.
Example
explain plan for select field1, field2 from TABLE_NAME;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
Check that all queries end with a semicolon, put the cursor on the query you want to analyze and hit CTRL-E.
The first time you could get a popup that asks for the name of the plan table, it suggests TOAD_PLAN_TABLE but it's better to use the standard Oracle table PLAN_TABLE that should be already available. So enter PLAN_TABLE in place of TOAD_PLAN_TABLE (do not specify a schema) and hit OK. You should get a message saying that the object already exists: hit OK again to acknowledge it. Now try CTRL-E again and you'll get the explain plan.
To view/change the currently configured plan table name go to menu "View / Toad Options / Oracle General".

Oracle AUTOTRACE alternative

I need collect statistics for my long SQL-scripts. Script files generated by Java application and execute by third-party fast DB-driver.
In this way I can't use AUTOTRACE, because it`s not SQLPlus. But for perfomance reasons I need to know stat information about every statement in script.
Can you advice approaches or best practices?
I look in the direction of STATSPACK and secondarily tkproof.
1. STATSPACK looks like machine that breaks a butterfly on a wheel. Isn`t it?
2. tkproof needs kind of privileges and I worry that the Java application user does not have such privileges.
Is there something else?
You can get some statistics from v$sql:
SELECT q.*
FROM v$session s
, v$sql q
WHERE s.sql_address = q.address
AND s.sql_hash_value = q.hash_value
AND s.sid = :SID
;
There is also v$session_longops which shows all operations which run for more than 6 seconds.
The only escalated privilege an Oracle user needs to generate a trace file is ALTER SESSION. You may not even need that if your user has execute on SYS.DBMS_MONITOR, as the SESSION_TRACE_ENABLE and SESSION_TRACE_DISABLE allow instantiation of tracing.
On the other hand, retrieving the trace file requires either the assistance of the DBA or the DBA to perform configuration to allow trace files to be public (a bad idea on production). Dion Cho has an excellent example of how to enable Oracle trace files to be queried here.

Resources