How to add a sequence column to an existing table with records - sql

I had created a new table named USERLOG with two fields from a previous VIEW. The table already consist of about 9000 records. The two fields taken from the VIEW, i.e. weblog_views consist of IP (consists of IP address), and WEB_LINK (consists of URL). This is the code I used,
CREATE TABLE USERLOG
AS
SELECT C_IP, WEB_LINK FROM weblog_views;
I want to add another column to this table called the USER_ID, which would consists of a sequence starting with 1 to 9000 records to create a unique id for each existing rows. I need help with this part. I'm using Oracle SQL Developer: ODMiner version 3.0.04.
I tried using the AUTO-INCREMENT option,
ALTER TABLE USERLOG
ADD USER_ID INT UNSIGNED NOT NULL AUTO_INCREMENT;
But I get an error with this,
Error report:
SQL Error: ORA-01735: invalid ALTER TABLE option
01735. 00000 - "invalid ALTER TABLE option"
So, I would really appreciate any help that I can get!

You would need to add a column
ALTER TABLE userlog
ADD( user_id number );
create a sequence
CREATE SEQUENCE user_id_seq
START WITH 1
INCREMENT BY 1
CACHE 20;
Update the data in the table
UPDATE userlog
SET user_id = user_id_seq.nextval
Assuming that you want user_id to be the primary key, you would then add the primary key constraint
ALTER TABLE userlog
ADD CONSTRAINT pk_user_id PRIMARY KEY( user_id );
If you want to use the sequence to automatically add the user_id when you do an INSERT (the other option would be to specifically reference user_id_seq.nextval in your INSERT statements, you would also need a trigger
CREATE OR REPLACE TRIGGER trg_userlog_user_id
BEFORE INSERT ON userlog
FOR EACH ROW
BEGIN
:new.user_id := user_id_seq.nextval;
END;

In addition to Justin's excellent answer you might want to prevent NULL values for your user_id in the future (as they could still be caused by UPDATE statements). Therefore, execute the following statement at the end:
ALTER TABLE userlog MODIFY(user_id number NOT NULL);

Step 1.
Create sequence to be used by the column
eg:
CREATE SEQUENCE user_id_seq
START WITH 1
INCREMENT BY 1
CACHE 20;
Step 2.
Update new column with sequence
eg:
UPDATE userlog
SET user_id = user_id_seq.nextval;
Step 3. - Set Sequence as the default value for the column, will work only above Oracle 12c
ALTER TABLE USERLOG
MODIFY USER_ID INT DEFAULT user_id_seq.nextval;

Related

Missing Keyword Error in Oracle SQL Database [duplicate]

I was wondering how can I add an identity column to existing oracle table? I am using oracle 11g. Suppose I have a table named DEGREE and I am going to add an identity column to that.
FYI table is not empty.
You can not do it in one step. Instead,
Alter the table and add the column (without primary key constraint)
ALTER TABLE DEGREE ADD (Ident NUMBER(10));
Fill the new column with data which will fulfill the primary key constraint (unique/not null), e.g. like
UPDATE DEGREE SET Ident=ROWNUM;
Alter the table and add the constraint to the column
ALTER TABLE DEGREE MODIFY (Ident PRIMARY KEY);
After that is done, you can set up a SEQUENCE and a BEFORE INSERT trigger to automatically set the id value for new records.
From Oracle 12c you would use an identity column.
For example, say your table is called demo and has 3 columns and 100 rows:
create table demo (col1, col2, col3)
as
select dbms_random.value(1,10), dbms_random.value(1,10), dbms_random.value(1,10)
from dual connect by rownum <= 100;
You could add an identity column using:
alter table demo add demo_id integer generated by default on null as identity;
update demo set demo_id = rownum;
Then reset the internal sequence to match the data and prevent manual inserts:
alter table demo modify demo_id generated always as identity start with limit value;
and define it as the primary key:
alter table demo add constraint demo_pk primary key (demo_id);
This leaves the new column at the end of the column list, which shouldn’t normally matter (except for tables with a large number of columns and row chaining issues), but it looks odd when you describe the table. However, we can at least tidy up the dictionary order using the invisible/visible hack:
SQL> desc demo
Name Null? Type
-------------------------------- -------- ----------------------
COL1 NUMBER
COL2 NUMBER
COL3 NUMBER
DEMO_ID NOT NULL NUMBER(38)
begin
for r in (
select column_name from user_tab_columns c
where c.table_name = 'DEMO'
and c.column_name <> 'DEMO_ID'
order by c.column_id
)
loop
execute immediate 'alter table demo modify '||r.column_name||' invisible';
execute immediate 'alter table demo modify '||r.column_name||' visible';
end loop;
end;
/
SQL> desc demo
Name Null? Type
-------------------------------- -------- ----------------------
DEMO_ID NOT NULL NUMBER(38)
COL1 NUMBER
COL2 NUMBER
COL3 NUMBER
One thing you can't do (as of Oracle 18.0) is alter an existing column to make it into an identity column, so you have to either go through a process like the one above but copying the existing values and finally dropping the old column, or else define a new table explicitly with the identity column in place and copy the data across in a separate step. Otherwise you'll get:
-- DEMO_ID column exists but is currently not an identity column:
alter table demo modify demo_id generated by default on null as identity start with limit value;
-- Fails with:
ORA-30673: column to be modified is not an identity column
add the column
alter table table_name add (id INTEGER);
create a sequence table_name_id_seq with start with clause, using number of rows in the table + 1 or another safe value(we don't want duplicate ids);
lock the table (no inserts)
alter table table_name lock exclusive mode;
fill the column
update table_name set id = rownum; --or another logic
add a trigger to automaticaly put the id on insert using the sequence(you can find examples on internet, for example this answer)
When you'll fire the create trigger the lock will be released. (it automatically commits).
Also, you may add unique constraint on the id column, it is best to do so.
For Oracle :
CREATE TABLE new_table AS (SELECT ROWNUM AS id, ta.* FROM old_table ta)
remember this id column is not auto incremented

How to modify column to auto increment in PL SQL Developer?

I have created one table in PL SQL Developer.
CREATE TABLE Patient_List
(
Patient_ID number NOT NULL,
Patient_Name varchar(50) NOT NULL,
Patient_Address varchar(100) NULL,
App_Date date NULL,
Descr varchar(50),
CONSTRAINT patient_pk PRIMARY KEY(Patient_ID)
);
I want to auto increment Patient_ID, I tried altering the table and modifying the Patient_ID column but it's showing an error "invalid ALTER TABLE option"
ALTER TABLE Patient_List
MODIFY Patient_ID NUMBER NOT NULL GENERATED ALWAYS AS IDENTITY;
Please help, Thanks in advance.
This is not possible.
Oracle 10g didn't even have identity columns, they were introduced in Oracle 12.1
But even with a current Oracle version, you can't convert a regular column to an identity column. You would need to add a new one.
Before identity columns, the usual way was to create a sequence and a trigger to populate the column.
See here: How to create id with AUTO_INCREMENT on Oracle?
If anybody wants to modify existing column as auto_increment use this three lines
alter table Product drop column test_id;
create sequence Product_test_id_seq INCREMENT BY 1 nocache;
alter table Product add test_id Number default Product_test_id_seq.nextval not null;

DB2 add auto increment column to an existing table

I have a table with following schema in my DB2 database.
CREATE TABLE IDN_OAUTH_CONSUMER_APPS (
CONSUMER_KEY VARCHAR (255) NOT NULL,
CONSUMER_SECRET VARCHAR (512),
USERNAME VARCHAR (255),
TENANT_ID INTEGER DEFAULT 0,
APP_NAME VARCHAR (255),
OAUTH_VERSION VARCHAR (128),
CALLBACK_URL VARCHAR (1024),
GRANT_TYPES VARCHAR (1024)
/
I need to add a new column ID of Type integer not null auto increment, and make it the primary key. How can I do that without deleting the table?
I could do this successfully using following set of queries.
ALTER TABLE IDN_OAUTH_CONSUMER_APPS ADD COLUMN ID INTEGER NOT NULL DEFAULT 0
CREATE SEQUENCE IDN_OAUTH_CONSUMER_APPS_SEQUENCE START WITH 1 INCREMENT BY 1 NOCACHE
CREATE TRIGGER IDN_OAUTH_CONSUMER_APPS_TRIGGER NO CASCADE BEFORE INSERT ON IDN_OAUTH_CONSUMER_APPS REFERENCING NEW AS NEW FOR EACH ROW MODE DB2SQL BEGIN ATOMIC SET (NEW.ID) = (NEXTVAL FOR IDN_OAUTH_CONSUMER_APPS_SEQUENCE); END
REORG TABLE IDN_OAUTH_CONSUMER_APPS
UPDATE IDN_OAUTH_CONSUMER_APPS SET ID = IDN_OAUTH_CONSUMER_APPS_SEQUENCE.NEXTVAL
And then add primary key using alter table.
Use a multi-step approach:
add the column ALTER TABLE ADD... with just the integer data type and as nullable
update the table to set the intended identity values for that column
alter the table to add the auto-generation
alter the table to add the primary key on that column
You need to have multiple steps because the identity values need to be added manually. Syntax and examples for ALTER TABLE can be found here.
There is an easy way to do it. Just run the alters above:
ALTER TABLE idn_oauth_consumer_apps ADD COLUMN id INTEGER NOT NULL DEFAULT 0;
ALTER TABLE idn_oauth_consumer_apps ALTER COLUMN id SET GENERATED ALWAYS AS IDENTITY;
It is simple and fast even on big tables. Tested and working on DB2 for i V7R2.
I recommend using this approach. It does not require creating any satellite objects - no triggers, sequences, etc...
alter table test.test2 add column id integer not null default 0;
alter table test.test2 alter column id drop default;
alter table test.test2 alter column id set generated always as identity;
call sysproc.admin_cmd ('reorg table test.test2');
update test.test2 set id = default;
commit;
If using "db2" cli then the reorg command may be run directly without the "call sysproc.admin_cmd" wrapper.
Create a new table with the primary key field. Insert the records from the old table. Drop the old table and if you can, rename the new one. If you can't rename it, recreate it and populate from the one that now has the records.
Building on Chamila Wijayarathna's answer, I used the following:
ALTER TABLE IDN_OAUTH_CONSUMER_APPS ADD COLUMN ID INTEGER NOT NULL DEFAULT 0
CREATE SEQUENCE IDN_OAUTH_CONSUMER_APPS_ID_SEQUENCE START WITH 1 INCREMENT BY 1 NOCACHE
CREATE TRIGGER IDN_OAUTH_CONSUMER_APPS_ID_TRIGGER NO CASCADE BEFORE INSERT ON
IDN_OAUTH_CONSUMER_APPS REFERENCING NEW AS NEW
FOR EACH ROW MODE DB2SQL BEGIN ATOMIC SET (NEW.ID) = (NEXTVAL FOR
IDN_OAUTH_CONSUMER_APPS_ID_SEQUENCE); END
REORG TABLE IDN_OAUTH_CONSUMER_APPS
UPDATE IDN_OAUTH_CONSUMER_APPS SET ID = IDN_OAUTH_CONSUMER_APPS_ID_SEQUENCE.NEXTVAL
ALTER TABLE IDN_OAUTH_CONSUMER_APPS ADD PRIMARY KEY (ID)
REORG TABLE IDN_OAUTH_CONSUMER_APPS
Then to reverse:
REORG TABLE IDN_OAUTH_CONSUMER_APPS
ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP PRIMARY KEY
DROP TRIGGER IDN_OAUTH_CONSUMER_APPS_ID_TRIGGER
DROP SEQUENCE IDN_OAUTH_CONSUMER_APPS_ID_SEQUENCE
ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP COLUMN ID
REORG TABLE IDN_OAUTH_CONSUMER_APPS
Tried this on DB2 for z/OS v12 and it worked:
alter table TABLE_NAME add column id integer generated always as identity

SQL Server Database unique number generation on any record insertion

I have like 11 columns in my database table and i am inserting data in 10 of them. i want to have a unique number like "1101 and so on" in the 11th column.
Any idea what should i do?? Thanks in advance.
SQL Server 2012 and above you can generate Sequence
Create SEQUENCE RandomSeq
start with 1001
increment by 1
Go
Insert into YourTable(Id,col1...)
Select NEXT VALUE FOR RandomSeq,col1....
or else you can use Identity
Identity(seed,increment)
You can start the seed from 1101 and increment the sequence by 1
Create table YourTable
(
id INT IDENTITY(1101,1),
Col varchar(10)
)
If you want to have that unique number in a different field then you can manipulate that field with primary key and insert that value.
If you want in primary key value, then open the table in design mode, go to 'Identity specification', set 'identity increment' and 'identity seed' as you want.
Alternatively you can use table script like,
CREATE TABLE Persons
(
ID int IDENTITY(12,1) PRIMARY KEY,
FName varchar(255) NOT NULL,
)
here the primary key will start seeding from 12 and seed value will be 1.
If you have your table definition already in place you can alter the column and add Computed column marked as persisted as:
ALTER TABLE tablename drop column column11;
ALTER TABLE tablename add column11 as '11'
+right('000000'+cast(ID as varchar(10)), 2) PERSISTED ;
--You can change the right operator value from 2 to any as per the requirements.
--Also replace ID with the identity column in your table.
create table inc
(
id int identity(1100,1),
somec char
)

Can a sql server table have two identity columns?

I need to have one column as the primary key and another to auto increment an order number field. Is this possible?
EDIT: I think I'll just use a composite number as the order number. Thanks anyways.
CREATE TABLE [dbo].[Foo](
[FooId] [int] IDENTITY(1,1) NOT NULL,
[BarId] [int] IDENTITY(1,1) NOT NULL
)
returns
Msg 2744, Level 16, State 2, Line 1
Multiple identity columns specified for table 'Foo'. Only one identity column per table is allowed.
So, no, you can't have two identity columns. You can of course make the primary key not auto increment (identity).
Edit: msdn:CREATE TABLE (Transact-SQL) and CREATE TABLE (SQL Server 2000):
Only one identity column can be created per table.
You can use Sequence for second column with default value IF you use SQL Server 2012
--Create the Test schema
CREATE SCHEMA Test ;
GO
-- Create a sequence
CREATE SEQUENCE Test.SORT_ID_seq
START WITH 1
INCREMENT BY 1 ;
GO
-- Create a table
CREATE TABLE Test.Foo
(PK_ID int IDENTITY (1,1) PRIMARY KEY,
SORT_ID int not null DEFAULT (NEXT VALUE FOR Test.SORT_ID_seq));
GO
INSERT INTO Test.Foo VALUES ( DEFAULT )
INSERT INTO Test.Foo VALUES ( DEFAULT )
INSERT INTO Test.Foo VALUES ( DEFAULT )
SELECT * FROM Test.Foo
-- Cleanup
--DROP TABLE Test.Foo
--DROP SEQUENCE Test.SORT_ID_seq
--DROP SCHEMA Test
http://technet.microsoft.com/en-us/library/ff878058.aspx
Add one identity column and then add a computed column whose formula is the name of the identity column
Now both will increment at the same time
No it is not possible to have more than one identity column.
The Enterprise Manager does not even allow you to set > 1 column as identity. When a second column is made identity
Also note that ##identity returns the last identity value for the open connection which would be meaningless if more than one identity column was possible for a table.
create table #tblStudent
(
ID int primary key identity(1,1),
Number UNIQUEIDENTIFIER DEFAULT NEWID(),
Name nvarchar(50)
)
Two identity column is not possible but if you accept to use a unique identifier column then this code does the same job as well. And also you need an extra column - Name column- for inserting values.
Example usage:
insert into #tblStudent(Name) values('Ali')
select * from #tblStudent
Ps: NewID() function creates a unique value of type uniqueidentifier.
The primary key doesn't need to be an identity column.
You can't have two Identity columns.
You could get something close to what you want with a trigger...
in sql server it's not possible to have more than one column as identity.
I've just created a code that will allow you inserting two identities on the same table. let me share it with you in case it helps:
create trigger UpdateSecondTableIdentity
On TableName For INSERT
as
update TableName
set SecondIdentityColumn = 1000000+##IDENTITY
where ForstId = ##IDENTITY;
Thanks,
A workaround would be to create an INSERT Trigger that increments a counter.
So I have a table that has one identity col : applicationstatusid. its also the primary key.
I want to auto increment another col: applicationnumber
So this is the trigger I write.
create trigger [applicationstatus_insert] on [ApplicationStatus] after insert as
update [Applicationstatus]
set [Applicationstatus].applicationnumber =(applicationstatusid+ 4000000)
from [Applicationstatus]
inner join inserted on [applicationstatus].applicationstatusid = inserted.applicationstatusid