how to add primary key column without truncating table in oracle - sql

We have received a requirement where we need to add a new column to primary key where table is having records:
alter table customer add (bill_to number(9,0),
CONSTRAINT CUSTOMER_PK PRIMARY KEY (bill_to));
In this case after it adds the new column to the table by default null values will be stored if table is having records, technically we cannot make this column a primary key, either table shouldn't have the records or we have to truncate the table, but we cannot do it in production,
is there any other way to deal this? please suggest.

You can do it in 2 statements by first adding an IDENTITY column and second making it the PRIMARY KEY:
So, if you have the table:
CREATE TABLE customer ( value ) AS
SELECT 'A' FROM DUAL CONNECT BY LEVEL <= 3 UNION ALL
SELECT 'B' FROM DUAL CONNECT BY LEVEL <= 2;
Then you can:
ALTER TABLE customer ADD (
bill_to NUMBER(9,0)
GENERATED ALWAYS AS IDENTITY
);
ALTER TABLE customer ADD CONSTRAINT CUSTOMER_PK PRIMARY KEY ( bill_to );
And the table becomes:
VALUE | BILL_TO
:---- | ------:
A | 1
A | 2
A | 3
B | 4
B | 5
db<>fiddle here

You can not do it in a single statement.
You can achieve it using the three-step process as follows:
ALTER TABLE CUSTOMER ADD BILL_TO NUMBER(9, 0);
UPDATE CUSTOMER
SET BILL_TO = SEQ OR ANYOTHER LOGIC FOR UNIQUE VALUE FOR EACH ROW;
ALTER TABLE CUSTOMER ADD CONSTRAINT CUSTOMER_PK PRIMARY KEY ( BILL_TO );

Related

How to update table with sequentional on table without primary key?

In DB2 on Linux v11.1 I have a table:
COL1 COL2 "COLn 50 more columns"
A A
A A
B A
B B
etc 3 million rows
There can be multiple rows with the same rows, like first two rows in my sample (so obvious there is no primary key on table).
Now I have to add new column ID and set for every row unique sequential number.
The result should be:
COL1 COL2 "COLn 50 more columns" ID
A A 1
A A 2
B A 3
B B 4
etc 3 million rows
How to write such an update statement to update ID column?
Regards
Here is one way to do it, using an identity column , and it assumes that there is not an existing Primary Key or identity column.
alter table myschema.mytab add column id integer not null default 0 ;
alter table myschema.mytab alter column id drop default ;
alter table myschema.mytab alter column id set generated always as identity ;
update myschema.mytab set id = default ;
-- optional, if you want the new ID column to be a surrogate primary key
alter table myschema.mytab add constraint pkey primary key(id) ;
reorg table myschema.mytab ;
runstats on table myschema.mytab with distribution and detailed indexes all;
Try this:
alter table myschema.mytab add column id integer not null default 0 ;
UPDATE (SELECT ID, ROWNUMBER() OVER() RN FROM myschema.mytab) SET ID = RN;
-- Or even simplier:
-- UPDATE myschema.mytab SET ID = ROWNUMBER() OVER();

How to update unique table row numbers before inserting new row at existing position

SQL table:
id | name
----+--------
1 | apple
2 | orange
3 | apricot
The id is primary key, unique, could be SERIES. The goal is to insert new row where id equals 2 and shift existing row numbers below, that is 2 and 3, to 3 and 4 position.
I have tried shift rows before inserting new row:
"UPDATE some_table SET id = id + 1 WHERE id >= id"
but an error occurred:
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "some_table_pkey"
Detail: Key (id)=(3) already exists.
Is there some effective way to do such an operation?
The table should look like this after update:
id | name
----+--------
1 | apple
2 | cherry
3 | orange
4 | apricot
While I think the attempt is futile, you can achieve that by marking the primary key constraint as deferrable:
CREATE TABLE some_table
(
id int,
name text
);
alter table some_table
add constraint pk_some_table
primary key (id)
deferrable initially immediate; --<< HERE
In that case the PK constraint is evaluated at per statement, not per row.
Online example: https://rextester.com/JSIV60771
update Names
set id=id+1
where id in
(select id from Names where id>=2 order by id desc);
Here first you can update the id's and then you can insert
insert into Names (id,name) values(2,'cheery')

SQL multiple insert select in one row

I'm new in SQL and I'm trying to put values in my table that has two foreign keys.
CREATE TABLE ROOM
(
ROOM_NAME VARCHAR2(40 BYTE)
, PATIENT_ID NUMBER
, DOC_NAME VARCHAR2(50 BYTE)
)
LOGGING
TABLESPACE USERS
PCTFREE 10
INITRANS 1
STORAGE
(
INITIAL 65536
NEXT 1048576
MINEXTENTS 1
MAXEXTENTS UNLIMITED
BUFFER_POOL DEFAULT
)
NOPARALLEL;
ALTER TABLE ROOM
ADD CONSTRAINT DOC_ROOM FOREIGN KEY (DOC_NAME)
REFERENCES DOCTOR(DOC_NAME) ENABLE;
ALTER TABLE ROOM
ADD CONSTRAINT PATIENT_ROOM FOREIGN KEY (PATIENT_ID)
REFERENCES RECORD(ID) ENABLE;
Created using the left panel in SQL Developer. As you can see I have two foreign keys. I have no idea how to add values to the columns Patient_ID and Doc_Name.
So far what I did was just inserting one by one into the table, but that resulted in having three different rows.
What I got:
ROOM_NAME | PATIENT_ID | DOC_NAME
---------------------------------------
Emergency Room | NULL | NULL
NULL | 1 | NULL
NULL | NULL | Dr. John
What I want to get:
ROOM_NAME | PATIENT_ID | DOC_NAME
---------------------------------------
Emergency Room | 1 | Dr. John
insert will always create a new row (unless some constraint is violated).
To insert a row with all values at once, use this:
insert into room
(ROOM_NAME, PATIENT_ID, DOC_NAME)
values
('Emergency Room', 1, 'Dr. John');
If you want to change an already existing row, you need to use the UPDATE statement, e.g:
update room
set doc_name = 'Dr. House'
where room_name = 'Emergency Room'
and patient_id = 1;
Your room table is missing a primary key, you should add one that uniquely identifies rows in this table.
Nevermind. Saw the answer from another question.
insert into room values ('EmergencyRoom', (Select id from record where id = 1), (select doc_name from DOCTOR where doc_name = 'Dr. John'))

create unique numerical identifier column in oracle sql

I have a table that has a list of states. I did this to create the table:
CREATE TABLE drb (
Statename VARCHAR2(15)
)
I then inserted the state data. However, I want my first column to be a created unique state ID. So it should list 1-50 for the 50 states in the United States. I tried searching different unique tutorials like this and nothing seemed to work.
Essentially, I want to know how to get a unique numerical key for a variable
Your table should have id field along with statename, add it this way.
CREATE TABLE drb (
id NUMBER,
Statename VARCHAR2(15)
);
Make id as primary key:
alter table drb
add constraint drb_pk primary key (id);
Create a sequence as follows:
create ore replace sequence drb_sequence
start with 1 increment by 1;
Create a trigger which will insert a unique id into drb table as follows:
create or replace trigger drb_trigger
before insert on drb
for each row
begin
select drb_sequence.nextval into :new.id from dual;
end;
/
Now insert into drb:
insert into drb(Statename) values('state one');
Select from drb:
select * from drb;
Output :
--------------------------
|id Statename |
--------------------------
|1 state one |
--------------------------
Hope it helps.

How to Insert Primary Value (PK) to Related Table (FK)

I'm having trouble from Inserting 1 Primary Value (Increment) of TABLE to another TABLE (Foreign Key)
Table 1 has the Primary key of Student Number; if i enter values for last and first name from TABLE 1 then the student number will automatically giving it's own value because of Increment, and else if i entered from TABLE 2, I want the value of Student Number from TABLE i will increment even the value of Last and First name if TABLE 1 is NULL
Table 1
(PK)Student_# | Last_Name | First_Name
...........1...........|........a..........|..........b.......
...........2...........|........c..........|..........b.......
Table 2
(FK)Student_# | Year_Level | Section
...........NULL................|..........2nd Year......|.....C1 .........
...........NULL................|..........3rd Year......|.....D1 .........
Needed
(FK)Student_# | Year_Level | Section
..............1...................|..........2nd Year......|.....C1 .........
..............2...................|..........3rd Year......|.....D1 .........
It sounds to me that you need a primary key with an identity seed on table2 and also a foreign key to the student table:
(PK/Identity) Table2ID | (FK)Student_# | Year_Level | Section
This way you can insert the student_# when you insert the record into table 2 and also be able to give each row in table2 a unique identifier
CREATE TABLE Table2
(
Table2ID INT IDENTITY(1,1) PRIMARY KEY
,Student_# INT NOT NULL FOREIGN KEY REFERENCES Table1(Student_#)
,Year_Level NVARCHAR(255) --Use whatever data type you need
,Section NVARCHAR(255) --Use whatever data type you need
)
I have assumed you are using sql server as you have not specified in your question. You may need to change this query for a different RDBMS.