Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

New PK in existing table

Status
Not open for further replies.

Andrzejek

Programmer
Jan 10, 2006
8,486
5
38
US
Imagine you have a table in the data base for a few years with lots of records and finally you want to introduce a Primary Key field to that table (I know, it should be done from the start).

Is there an easy way to Update this PK field with some simple, easy Update statement? Something with the ROWNUM maybe...?
You know, each record should get its own, unique number, order does not matter, as long as 1000 records get the numbers from 1 to 1000.


Have fun.

---- Andy

A bus station is where a bus stops. A train station is where a train stops. On my desk, I have a work station.
 
I just tried:
[tt]
UPDATE MyTable
SET SomePKField = ROWNUM
[/tt]
and it seams to work.
I just don't know how reliable this syntax is. And is there a better way to do it?

Have fun.

---- Andy

A bus station is where a bus stops. A train station is where a train stops. On my desk, I have a work station.
 
Do it right, make a sequence that you can use for any later row inserts and if you don't want to change your code to set the value do the following. Please replace the name MY_TABLE and MY_KEY with the real table name and the name of the column that you want to add.

CREATE SEQUENCE MY_TABLE_S1
START WITH 0
INCREMENT BY 1
MINVALUE 0
CACHE 20
NOCYCLE
NOORDER;

THEN ADD YOUR NEW PRIMARY KEY COLUMN or use and existing column if you have to.

ALTER TABLE MY_TABLE ADD (MY_KEY NUMBER(38));

Now add a trigger to always maintain the column on new inserts

CREATE TRIGGER MY_TABLE_T1
BEFORE INSERT
ON MY_TABLE
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
N NUMBER;
BEGIN
-- For Toad: Highlight column REFUND_BALANCE
SELECT MY_TABLE_S1.NEXTVAL INTO n FROM dual;
:NEW.MY_KEY := N;
END MY_TABLE_T1;
/


Then set the new primary key column

UPDATE MY_TABLE
SET MY_KEY = MY_TABLE_S1.NEXTVAL;

COMMIT;

Now enforce and index the primary key

ALTER TABLE MY_TABLE ADD
CONSTRAINT MY_TABLE_PK
PRIMARY KEY (MY_KEY)
ENABLE
VALIDATE;

********* Your all set ***********








Bill
Lead Application Developer
New York State, USA
 
Thank you Beilstwh,

I was working under the assumption that I would:
1. Add a field (that eventually will become a PK)
2. Populate it with unique values (that's why the question)
3. Set it as PK
4. introduce a sequence
5. Set the next value of a sequence to the last PK + 1
6. And set up a trigger on Insert

Now I see a better / faster way to do it:
1. Add a field (that eventually will become a PK)
2. introduce a sequence
3. Run this: UPDATE MY_TABLE SET MY_KEY = MY_TABLE_S1.NEXTVAL
4. Set it as PK
6. And set up a trigger on Insert

As a side question - is it a good idea to have a sequence / trigger on a small, look-up table that does not get (any or very seldom) Inserts? Is it 'over-kill' to do that?


Have fun.

---- Andy

A bus station is where a bus stops. A train station is where a train stops. On my desk, I have a work station.
 
The only reason that I added the trigger was because I assumed that you didn't want to modify the code. If you are always going to go through the same code you can change the insert to

insert into my_table(my_key,col1,col2) values(my_table_s1.nextval,1,2);

if you do that you will not need the trigger. Either way is valid.

Bill
Lead Application Developer
New York State, USA
 
Sticking with your original approach, this should work...

Code:
UPDATE  MyTable
SET     SomePKField = ROWID
WHERE   ROWNUM <= 1000;

ROWIDs are unique to each row.

But Beilstwh's approach is more correct.


 
Remember that the actual rowid's for a table may change. I would not use a rowid, I would use a sequence. As a general rule never store and then expect to use a rowid.

Bill
Lead Application Developer
New York State, USA
 
I do want to have the tables set up right – PK, sequence, trigger on Insert, done. But in many cases I need to ‘catch-up’ first with the tables that do not have PKs (bad idea, I know, not my idea). That’s why I want to fix it wherever I can.

Thanks for the input.

Have fun.

---- Andy

A bus station is where a bus stops. A train station is where a train stops. On my desk, I have a work station.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top