i have delete some duplicates in table which is paritioned using LIST for status Y and N. I have deleted duplicates which are active
delete from my_table partition(active_flag_y) where rowid = ( duplicate logic )
Post delete i started running my Informatica mapping which is having Update + insert logic.
While updating it is giving me
ORA-08006: specified row no longer exists
I am deleting using rowid but that rowid exists in my table.
Can someone help me with the solution
While updating it is giving me ORA-08006: specified row no longer exists
Include additional condition to update:
update your_table a
set ...
-- add this:
where exists (select null
from table_from_which_you_deleted_rows b
where b.rowid = a.rowid
);
Next question is: what will you do with rows in YOUR_TABLE whose ROWID doesn't exist in a table you're referencing?
As you noticed, ROWID isn't the best piece of information you can rely on. Documentation says:
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.
Related
I want to insert a one or more records in table A.
But same record already existing in records with status Active
CREATE PROCEDURE Test
AS
BEGIN
INSERT INTO A (x,y,z,status)
SELECT data FROM A WHERE some condtion;
... Here i want to update table A status column into 'N', if the inserted data already existing in table A Compared with x,y,z column.
EXCETION
---Handled
END;
You can try this:
MERGE INTO target_table t
USING source_table s
ON (t.id = s.id)
WHEN MATCHED THEN
UPDATE SET t.col1 = s.col1
WHEN NOT MATCHED THEN
INSERT (col1, col2) VALUES (s.col1, s.col2);
Documentation Link: https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016.htm#SQLRF01606
What you probably want to do is a merge-statement. The merge statement checks if the dataset already exists. In this case you can formulate an update statement. For example, you could update the status. If not, the new dataset will be inserted.
For further information you should hava a look here.
The merge is the way to go. Another approach is first updating all the rows that match the criteria and after do the insert.
However, if your problem is how to differentiate the 2 rows, use the pseudo-column ROWID.
I know that ROWID is distinct for each row in different tables.But,I am seeing somewhere that two tables are being merged using rowid.So,I also tried to see it,but I am getting the blank output.
I have person table which looks as:
scrowid is the column which contains rowid as:
alter table ot.person
add scrowid VARCHAR2(200) PRIMARY KEY;
I populated this person table as:
insert into ot.person(id,name,age,scrowid)
select id,name, age,a.rowid from ot.per a;
After this I also created another table ot.temp_person by same steps.Both table has same table structure and datatypes.So, i wanted to see them using inner join and I tried them as:
select * from ot.person p inner join ot.temp_person tp ON p.scrowid=tp.scrowid
I got my output as empty table:
Is there is any possible way I can merge two tables using rowid? Or I have forgotten some steps?If there is any way to join these two tables using rowid then suggest me.
Define scrowid as datatype ROWID or UROWID then it may work.
However, in general the ROWID may change at any time unless you lock the record, so it would be a poor key to join your tables.
I think perhaps you misunderstood the merging of two tables via rowid, unless what you actually saw was a Union, Cross Join, or Full Outer Join. Any attempt to match rowid, requardless of you define it, doomed to fail. This results from it being an internal definition. Rowid in not just a data type it is an internal structure (That is an older version of description but Oracle doesn't link documentation versions.) Those fields are basically:
- The data object number of the object
- The data block in the datafile in which the row resides
- The position of the row in the data block (first row is 0)
- The datafile in which the row resides (first file is 1). The file
number is relative to the tablespace.
So while it's possible for different tables to have the same rowid, it would be exteremly unlikely. Thus making an inner join on them always return null.
i want to update a partition key. the partition is as below
PARTITION_NAME LAST_ANALYZED NUM_ROWS BLOCKS SAMPLE_SIZE HIGH_VALUE
PORTAL_SERVICE_1 12/8/2016 4133 174 4133 1
PORTAL_SERVICE_2 6/8/2016 4474 174 4474 2
PORTAL_SERVICE_3 10/8/2016 29602 2014 29602 3
PORTAL_SERVICE_OTHERS 24/5/2016 0 110 DEFAULT
this partition is applied on column Portal_Service_id. i want to update the value of portal service id from 2 to 1.
when i try
update trans set PORTAL_SERVICE_ID = 1 where ID = 2054;
i get error:
Error report -
SQL Error: ORA-14402: updating partition key column would cause a partition change
14402. 00000 - "updating partition key column would cause a partition change"
i am not allowed to use Enable Row Movement.
Can anybody please suggest any alternative to update the row.
can anybody shed some light if this can be used in the scenario:
UPDATE <table_name> PARTITION (<partition_name>)
SET <column_name> = <value>
WHERE <column_name> <condition> <value>;
to work around the error "ORA-14402: updating partition key column would cause a partition change" you can follow these steps
1) Check if for your table is enabled the row_movement
SELECT owner,
table_name,
row_movement
FROM dba_tables
WHERE table_name in ('YOUR_TABLE');
2) If is disabled you can enable movement with this script
alter table YOUR_TABLE enable row movement;
After that you can update the partition key column
Most of the other answers have pointed out one part of the solution, which is:
alter table <table_name> enable row movement
However, there's more to it than this. Enabling row movement has some tradeoffs, which are pointed out here: http://www.dba-oracle.com/t_enable_row_movement.htm
In my case, this led me to double check why we were using a partition in the first place. Ideally, a partition is for data that won't move around once it's in the partition. If you're modifying the partition field (in my case a timestamp) then it may mean you shouldn't be using a partition. If you're sure you want a partition on a mutable field, then at least make sure you periodically run:
"alter table shrink compact"
I came across this question as the top Google result when searching for ORA-14402. In my particular case I:
exported the rows as insert statements
updated the index key field and updated the ID field
inserted the rows as new rows.
You could then potentially delete the old rows if you have the need or leave them in the old partition.
Enable row movement with this syntex , it will solve the error :
alter table <table_name> enable row movement
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?
I have a insert statement on table "test". PK on column x in the table "test".
Now while inserting if duplicate row comes then the same row should get updated instead insert.
How can i achieve this.
Is it possible by dup_val_on_index?
Please help.
First create a copy of the above table without any KEY Columns and follow
Step 1: truncate the table first whenever you encounter a bunch of insert statement comes
Step 2: INSERT the above truncated tables
Step 3: Execute the MERGE statement like below
MERGE INTO TABLE_MAIN M
USING TABLE_MAIN_COPY C
ON (m.id = c.id)
WHEN MATCHED THEN UPDATE SET M.somecol = c.somecol
WHEN NOT MATCHED THEN INSERT (m.id, m.somecol)
VALUES (c.id, c.somecol);
You may incur error while on merger ORA-30926: unable to get a stable set of rows in the source tables when there is two or more rows while on update.
you may avoid that using the GROUP function related to id or like ORA-30926: unable to get a stable set of rows in the source tables