开发者

Change primary key value in Oracle

Is there a way to change the value of a pr开发者_Go百科imary key which is referenced by another table as foreign key?


An easier alternative is to insert a new row and delete the old one. (Update any referencing rows in other tables before you do the delete)


There isn't an in-built UPDATE CASCADE if that's what you're after. You'd need to do something like disable any FK constraints; run UPDATE statements; re-enable the constraints.

Note that updating Primary Keys is (usually always) a bad idea.


You will need to disable the foreign key constraints before changing the primary key values, and then re-enable them afterwards.

If you actually want to implement "update cascade" functionality instead then see Tom Kyte's Update Cascade package


It is possible even without disabling constraints, in case if you would like only to swap keys (which is also a change's subset, so it might be still answer to your question). I wrote an example here: https://stackoverflow.com/a/26584576/1900739

update MY_TABLE t1
set t1.MY_KEY = (case t1.MY_KEY = 100 then 101 else 100 end)
where t1.MYKEY in (100, 101)


Yes, there is a way to do the cascading update in Oracle, even within a transaction (which does not hold true for the option of enabling/disabling constraints). However, you'll have to implement it yourself. It can be done via before/after-row-update triggers.

It is possible due to the fact that triggers are executed before any constraints are checked. (Well, at least in Oracle 11.2 it was true. Haven't checked against 12.1, but I honestly believe it hasn't changed.)

Anyway, as said before, updating primary keys is usually a bad idea.


The principe is to disable constrainsts, run your udates based on key, and reenable the constrainst. That for here is a script that run the disable script : (Assuming all the constraints are enable at start)

Generate the script SELECT 'alter table ' || uc.table_name|| ' disable constraint '|| uc.constraint_name|| ' ;' FROM user_constraints uc inner join user_cons_columns ucc on uc.constraint_name = ucc.constraint_name where column_name = 'MYCOLUMN_USED_AS_FOREIGN_KEY' and constraint_type='R' Copy/paste the generated script and run it

alter table MYTABLE1 disable constraint FK_MYTABLE1 ; alter table MYTABLE2 disable constraint MYTABLE2 ; alter table MYTABLE3 disable constraint FK3_MYTABLE3 ; ...

Then update your PK values : update MYTABLE1 set MYFIELD= 'foo' where MYFIELD='bar'; update MYTABLE2 set MYFIELD= 'foo' where MYFIELD='bar'; update MYTABLE3 set MYFIELD= 'foo' where MYFIELD='bar'; commit; Generate the enable constraints script :

SELECT 'alter table ' || uc.table_name|| ' enable constraint '|| uc.constraint_name|| ' ;' FROM user_constraints uc inner join user_cons_columns ucc on uc.constraint_name = ucc.constraint_name where column_name = 'MYCOLUMN_USED_AS_FOREIGN_KEY' and constraint_type='R'


Another way you can do this is by changing the foreign key constraints so that the validation of the constraint is deferred until you commit - i.e. instead of Oracle validating the constraints statement-by-statement, it'll do it transaction-by-transaction.

Note you can't do this via the "alter table" statement, but you can drop and re-create the foreign key constraint to be deferrable, i.e:

alter table <table name> drop constraint <FK constraint name>;
alter table <table name> add constraint <FK constraint name> foreign key .... initially deferrable;

Once you've done that, just update the tables in whatever order you like, and commit - at which point, either:

  1. All your FK constraints are satisfied, and everyone's happy; or
  2. You've violated a FK constraint somewhere - you'll get an error and you'll have to fix up the data and commit, or rollback.

Note this feature is quite safe, as Oracle does not allow dirty reads so they'll only see the effects of your updates once you commit. So from the perspective of every other session, referential integrity appears to be preserved.

Also, this is a once-off change, so you don't need to go executing DDL each time you want to go updating the primary keys.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜