Restore the truncated table data in Oracle [duplicate] - oracle

This question already has an answer here:
Use of FLASHBACK in Oracle
(1 answer)
Closed 6 years ago.
I am new to Oracle Advance concepts, In my application I have accidentally "truncate" the data. I am facing difficulty to
restore the truncated data. I googled about it alot, I found there is "FLASHBACK" command from oracle 10g. I tried it using timestamp approach in flashback
but I am getting the following error:
Error: The table definition has changed.
Could any body tell me how to get back my truncated table data?
Is it possible? If it is Please let me know the procedure to get back the data.

The error message is pretty clear. FLASHBACK is not available if you had DDL operations on the table (add or drop column, add or drop constraint, etc.) It's right there in the first paragraph in the documentation. http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9012.htm As Tim suggests - this is where backing up your data would have helped.
Edit: To be very precise, the wording in the Oracle documentation is (with my emphasis): Oracle Database cannot restore a table to an earlier state across any DDL operations that change the structure of the table. So adding or dropping a column will prevent the use of FLASHBACK since they change the structure of the table. TRUNCATE does not, so TRUNCATE by itself does not prevent FLASHBACK (although TRUNCATE is a DDL operation). I got carried away in the first paragraph with "add or drop constraint" - I actually don't know if that will prevent FLASHBACK; one can find out by experimenting.

Related

Does creating index in Oracle locks the table for reads?

If we specify ONLINE in the CREATE INDEX statement, the table isn't locked during creation of the index. Without ONLINE keyword it isn't possible to perform DML operations on the table. But is the SELECT statement possible on the table meanwhile? After reading the description of CREATE INDEX statement it still isn't clear to me.
I ask about this, because I wonder if it is similar to PostgreSQL or SQL Server:
In PostgreSQL writes on the table are not possible, but one can still read the table - see the CREATE INDEX doc > CONCURRENTLY parameter.
In SQL Server writes on the table are not possible, and additionally if we create a clustered index reads are also not possible - see the CREATE INDEX doc > ONLINE parameter.
Creating an index does NOT block other users from reading the table. In general, almost no Oracle DDL commands will prevent users from reading tables.
There are some DDL statements that can cause problems for readers. For example, if you TRUNCATE a table, other users who are in the middle of reading that table may get the error ORA-08103: Object No Longer Exists. But that's a very destructive change that we would expect to cause problems. I recently found a specific type of foreign key constraint that blocked reading the table, but that was likely a rare bug. I've caused a lot of production problems while adding objects, but so far I've never seen adding an index prevent users from reading the table.

How to (un)mark an Oracle table read-only for the owner?

In my Oracle instance I have a table. It existed just fine for many years without problems, I run thousands of queries per day on it (through my software), mostly selects and inserts, with rare (once-a-week) updates.
Today, a week after the last update, I ran an update against it and it failed with an ORA-00942: table or view does not exist.
I am the owner of that table. I'm pretty sure that database didn't change much during the week, certainly not this table.
I can select from it just fine: select * from table_x, but updates and inserts fail: insert into table_x select * from table_x where 1 = 0 with the weird ORA-00942.
Since I'm the owner, the usual visibility and privilege problems don't seem to apply, and googling, sadly, doesn't help. I'm sure I'm missing something really simple, so any suggestions are very welcome.
How did I make an Oracle table read-only (or invisible) for myself (the owner)?
It's partitioned (not sure if that helps). It's about 50GB in size, half of that indexes (not sure if that helps either).
EDIT: Here's a screenshot of the sample statement from PL/SQL Developer:
Once I ran the same situation, according to the trace file and little googling which referenced to Materialized View Log which is associated with master table.
Use the following command to drop the materialized view log
DROP MATERIALIZED VIEW LOG ON <table_x>

How is the TRUNCATE command in Oracle able to retrieve the structure of a table after dropping it?

The SQL command TRUNCATE in Oracle is faster than than DELETE FROM table; in that the TRUNATE comand first drops the specified table in it's entirely and then creates a new table with same structure (clarification may require in case I may be wrong). Since TRUNCATE is a part of DDL it implicitly issues COMMIT before being executed and after the completion of execution. If such is a case then, the table that is dropped by the TRUNCATE command is lost permanently with it's entire structure in the data dictionary. In such a scenario, how is the TRUNCATE command able to drop first the table and recreate the same with the same structure?
(Note that I work for Sybase in SQL Anywhere engineering and my answer comes from my knowledge of how truncate is implemented there, but I imagine it's similar in Oracle as well.)
I don't believe the table is actually dropped and re-created; the contents are simply thrown away. This is much faster than delete from <table> because no triggers need to be executed, and rather than deleting a row at a time (both from the table and the indexes), the server can simply throw away all pages that contain rows for that table and any indexes.
I thought a truncate (amoungst other things) simply reset the High Water Mark.
see: http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/statements_10007.htm#SQLRF01707
however in
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:2816964500346433991
It is clear that the data segment changes after a truncate.

How can I tell if a Materialized View in Oracle is being used?

We have some Materialized views in our Oracle 9i database that were created a long time ago, by a guy no longer working here. Is there an easy (or any) method to determine whether Oracle is using these views to serve queries? If they aren't being used any more, we'd like to get rid of them. But we don't want to discover after the fact that those views are the things that allow some random report to run in less than a few hours. The answer I'm dreaming of would be something like
SELECT last_used_date FROM dba_magic
WHERE materialized_view_name = 'peters_mview'
Even more awesome would be something that could tell me what actual SQL queries were using the materialized view. I realize I may have to settle for less.
If there is a solution that requires 10g, we are upgrading soon, so those answers would be useful also.
Oracle auditing can tell you this once configured as per the docs. Once configured, enable it by "AUDIT SELECT ON {name of materialized view}". The audit trail will be in the AUD$ table in the SYS schema.
One method other than auditing would be to read the v$segment_statistics view after one refresh and before the next refresh to see if there have been any reads. You'd have to account for any automatic statistics collection jobs also.
V$SQLAREA table has two columns which help identify the queries executed by the database.
SQL_TEXT - VARCHAR2(1000) - First thousand characters of the SQL text for the current cursor
SQL_FULLTEXT - CLOB - All characters of the SQL text for the current cursor
We can use this columns to find the queries using the said materialized views

Can I detect the version of a table's DDL in Oracle?

In Informix, I can do a select from the systables table, and can investigate its version column to see what numeric version a given table has. This column is incremented with every DDL statement that affects the given table. This means I have the ability to see whether a table's structure has changed since the last time I connected.
Is there a similar way to do this in Oracle?
Not really. The Oracle DBA/ALL/USER_OBJECTS view has a LAST_DDL_TIME column, but it is affected by operations other than structure changes.
You can do that (and more) with a DDL trigger that keeps track of changes to tables. There's an interesting article with example here.
If you really want to do so, you'd have to use Oracle's auditing functions to audit the changes. It could be as simple as:
AUDIT ALTER TABLE WHENEVER SUCCESSFUL on [schema I care about];
That would at least capture the successfuly changes, ignoring drops and creates. Unfortunately, unwinding the stack of the table's historical strucuture by mining the audit trail is left as an exercise to the reader in Oracle, or to licensing the Change Management Pack.
You could also roll your own auditing by writing system-event triggers which are invoked on DDL statements. You'd end up having to write your own SQL parser if you really wantedto see what was changing.

Resources