i am performing oracle table rollback using rowId:
so before each data injection, i record the max rowid of the table.
If anything went wrong, i will delete from table where rowid > max rowid recorded.
after deletion is executed, i can still see injected records.
please advice!
thanks,
Richard
A ROWID is :
A globally unique address for a row in a database.
It is not an identifier that will be incremented for each new row. A new row could use a previously used ROWID if the row that had this ROWID has been deleted.
Also note that Oracle could reuse an older block that has been freed for new rows (which would result in a lower ROWID). Oracle could also get extents in another data file with a lower file number than the file of the last ROWID. In most cases you can't control precisely where your new rows will end up physically so you should not rely on ROWID increasing.
Finally you shouldn't depend upon the current implementation of ROWID, it could change in future releases.
You could use a sequence or a timestamp column to identify new records. Or even a flag column.
Related
As per my design I want to fetch rowid as in
select rowid r from table_name;
into a C variable. I was wondering what is the max size / length in characters of the rowid.
Currently in one of the biggest tables in my DB we have the max length as 18 and its 18 throughout the table for rowid.
Thanks in advance.
Edit:
Currently the below block of code is iterated and used for multiple tables hence in-order to make the code flexible without introducing the need of defining every table's PK in the query we use ROWID.
select rowid from table_name ... where ....;
delete from table_name where rowid = selectedrowid;
I think as the rowid is picked and used then and there without storing it for future, it is safe to use in this particular scenario.
Please refer to below answer:
Is it safe to use ROWID to locate a Row/Record in Oracle?
I'd say no. This could be safe if for instance the application stores ROWID temporarily(say generating a list of select-able items, each identified with ROWID, but the list is routinely regenerated and not stored). But if ROWID is used in any persistent way it's not safe.
A physical ROWID has a fixed size in a given Oracle version, it does not depend on the number of rows in a table. It consists of the number of the datafile, the number of the block within this file, and the number of the row within this block. Therefore it is unique in the whole database and allows direct access to the block and row without any further lookup.
As things in the IT world continue to grow, it is safe to assume that the format will change in future.
Besides volume there are also structural changes, like the advent of transportable tablespaces, which made it necessary to store the object number (= internal number of the table/partition/subpartion) inside the ROWID.
Or the advent of Index organized tables (mentioned by #ibre5041), which look like a table, but are in reality just an index without such a physical address (because things are moving constantly in an index). This made it necessary to introduce UROWIDs which can store physical and index-based ROWIDs.
Please be aware that a ROWID can change, for instance if the row moves from one table partition to another one, or if the table is defragmented to fill the holes left by many DELETEs.
According documentation ROWID has a length of 10 Byte:
Rowids of Row Pieces
A rowid is effectively a 10-byte physical address of a row.
Every row in a heap-organized table has a rowid unique to this table
that corresponds to the physical address of a row piece. For table
clusters, rows in different tables that are in the same data block can
have the same rowid.
Oracle also documents the (current) format see, Rowid Format
In general you could use the ROWID in your application, provided the affected rows are locked!
Thus your statement may look like this:
CURSOR ... IS
select rowid from table_name ... where .... FOR UPDATE;
delete from table_name where rowid = selectedrowid;
see SELECT FOR UPDATE and FOR UPDATE Cursors
Oracle even provides a shortcut. Instead of where rowid = selectedrowid you can use WHERE CURRENT OF ...
According to Oracle Documentation
You should not use ROWID as the primary key of a table. If you delete
and reinsert a row with the Import and Export utilities, for example,
then its rowid may change. If you delete a row, then Oracle may
reassign its rowid to a new row inserted later.
I didn't understand the actual reason. Does it mean, when we use Import/Export utilities, then only we shouldn't use ROWID as primary key or we should never use ROWID as primary key ?
As explained above, when we delete the row and re-insert then same ROWID may get assign but on the other side the row was already deleted, so there won't be any problem if we get same ROWID. Isn't it ? Can anyone explain this with some example ?
If you rebuild your table then the ROWID of the table may change and you dont want your primary key to be changed.
Also if you delete one record then a new record could be given that ROWID. Also you should understand that ROWID does not persist across a database EXPORT and IMPORT process.
From here
If rows are moved, the ROWID will change. Rows can move due to
maintenance operations like shrinks and table moves. As a result,
storing ROWIDs for long periods of time is a bad idea. They should
only be used in a single transaction, preferably as part of a SELECT
... FOR UPDATE, where the row is locked, preventing row movement.
We should never use ROWIDs as primary keys for permanent and business-important data.
ROWID is a technical address of a row. There are several scenarious when
a) rowid of the existing records would be changed
b) different records would have the same rowid.
For example, if you have partitioned table, updating of record's partitioning key would bring us into record's rowid changing. Such scenarious prevents of using ROWID keys unless we can to forget it without serious consequences.
ROWID keys can be used for unnecessary temporary data, such as exceptions tables, or for short-term navigation, such as in WHERE CURRENT OF clause.
When deleting rows in the grid view, the message panel indicates that SQL Developer issues this delete command.
DELETE FROM "MH"."T" WHERE ROWID = 'AABUG+AAEAAEZtrAAA'
AND ORA_ROWSCN = '1220510600909'
and ( "A" is null or "A" is not null )
It seems specifying the ROWID should be sufficient to identify the row, so
Why does it specify ORA_ROWSCN?
And more befuddling, why the is null / not null clause?
The ROWID is just the physical address of the row. If one row is deleted and another row is inserted, the new row could have the same ROWID as the old row. If the data in the row had been modified, it is also possible that its ROWID could have changed. The ORA_ROWSCN criteria ensures that neither of these have actually happened. It also allows SQL Developer to alert you if another session had modified the data since you read it so that you can confirm that you still want to delete the row.
I'm at a loss for what the A is null or A is not null predicate would be adding. If it was the first predicate, I would guess that it was the standard 1 = 1 predicate that folks sometimes add to queries that are dynamically built to simplify the process of building the SQL statement dynamically. But that doesn't fit with it being the last predicate in the query. Is A the primary key of the table?
In my application I have created a column with sequence to have unique id for each and every record that I add,I doubt will there be any unique row-number created by oracle itself for every record we updated in table,if yes then how to access that row number like
SELECT row-number from table where employee_name='name';
here I want to get unique row number created by oracle,
I have searched on net but haven't got proper information
Oracle does maintain a ROWID for each row; however, in my opinion using ROWID in user-written code is both poor practice and dangerous. ROWID is only guaranteed to be constant for the duration of a single transaction. ROWID is not guaranteed to be constant forever and the database can change it if and when it determines that a change is necessary. If your data does not supply a value or combination of values which are unique and unchanging I strongly suggest you learn how to create an artificial key which is automatically set using sequences and triggers. I believe 12c supplies auto-increment columns which you can use if you're using the latest version of Oracle.
Share and enjoy.
There are 2 unique identifiers in Oracle named as ROWNUM and ROWID. You can use them in such ways:-
SELECT ROWNUM
FROM table
WHERE employee_name = 'name';
and
SELECT ROWID
FROM table
WHERE employee_name = 'name';
You can read further about them.
Rownum -
http://docs.oracle.com/cd/B12037_01/server.101/b10759/pseudocolumns008.htm
Rowid - http://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns008.htm
I just would like to hear different opinions about ROWID type usage as input parameter of any function or procedure.
I have normally used and seen primary keys used as input parameters but is there some kind of disadvantages to use ROWID as input parameter? I think it's kind a simple and selects are pretty quick if used in WHERE clause.
For example:
FUNCTION get_row(p_rowid IN ROWID) RETURN TABLE%ROWTYPE IS...
From the concept guide:
Physical rowids provide the fastest possible access to a row of a given table. They contain the physical address of a row (down to the specific block) and allow you to retrieve the row in a single block access. Oracle guarantees that as long as the row exists, its rowid does not change.
The main drawback of a ROWID is that while it is normally stable, it can change under some circumstances:
The table is rebuilt (ALTER TABLE MOVE...)
Export / Import obviously
Partition table with row movement enable
A primary key identifies a row logically, you will always find the correct row, even after a delete+insert. A ROWID identifies the row physically and is not as persistent as a primary key.
You can safely use ROWID in a single SQL statement since Oracle will guarantee the result is coherent, for example to remove duplicates in a table. To be on the safe side, I would suggest you only use the ROWID accross statements when you have a lock on the row (SELECT ... FOR UPDATE).
From a performance point of view, the Primary key access is a bit more expensive but you will normally notice this only if you do a lot of single row access. If performance is critical though, you usually can get greater benefit in that case from using set processing than single row processing with rowid. In particular, if there are a lot of roundtrips between the DB and the application, the cost of the row access will probably be negligible compared to the roundtrips cost.