Oracle Trigger for incrementing Integer value [duplicate] - oracle

This question already has answers here:
How to create id with AUTO_INCREMENT on Oracle?
(18 answers)
Closed 7 years ago.
I want to add a new auto increment primary column to a existing table which has data. How do I do that?
I first added a column and then try to add a sequence after that, I lost how to insert and make that column as primary key.

Say your table is called t1 and your primary-key is called id
First, create the sequence:
create sequence t1_seq start with 1 increment by 1 nomaxvalue;
Then create a trigger that increments upon insert:
create trigger t1_trigger
before insert on t1
for each row
begin
select t1_seq.nextval into :new.id from dual;
end;

If you have the column and the sequence, you first need to populate a new key for all the existing rows. Assuming you don't care which key is assigned to which row
UPDATE table_name
SET new_pk_column = sequence_name.nextval;
Once that's done, you can create the primary key constraint (this assumes that either there is no existing primary key constraint or that you have already dropped the existing primary key constraint)
ALTER TABLE table_name
ADD CONSTRAINT pk_table_name PRIMARY KEY( new_pk_column )
If you want to generate the key automatically, you'd need to add a trigger
CREATE TRIGGER trigger_name
BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
:new.new_pk_column := sequence_name.nextval;
END;
If you are on an older version of Oracle, the syntax is a bit more cumbersome
CREATE TRIGGER trigger_name
BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
SELECT sequence_name.nextval
INTO :new.new_pk_column
FROM dual;
END;

Snagged from Oracle OTN forums
Use alter table to add column, for example:
alter table tableName add(columnName NUMBER);
Then create a sequence:
CREATE SEQUENCE SEQ_ID
START WITH 1
INCREMENT BY 1
MAXVALUE 99999999
MINVALUE 1
NOCYCLE;
and, the use update to insert values in column like this
UPDATE tableName SET columnName = seq_test_id.NEXTVAL

You can use the Oracle Data Modeler to create auto incrementing surrogate keys.
Step 1. - Create a Relational Diagram
You can first create a Logical Diagram and Engineer to create the Relational Diagram or you can straightaway create the Relational Diagram.
Add the entity (table) that required to have auto incremented PK, select the type of the PK as Integer.
Step 2. - Edit PK Column Property
Get the properties of the PK column.
You can double click the name of the column or click on the 'Properties' button.
Column Properties dialog box appears.
Select the General Tab (Default Selection for the first time).
Then select both the 'Auto Increment' and 'Identity Column' check boxes.
Step 3. - Additional Information
Additional information relating to the auto increment can be specified by selecting the 'Auto Increment' tab.
Start With
Increment By
Min Value
Max Value
Cycle
Disable Cache
Order
Sequence Name
Trigger Name
Generate Trigger
It is usually a good idea to mention the sequence name, so that it will be useful in PL/SQL.
Click OK (Apply) to the Column Properties dialog box.
Click OK (Apply) to the Table Properties dialog box.
Table appears in the Relational Diagram.

Related

How to automatically insert foreign key into table after submit in oracle apex?

I have created forms in which the user can enter data. With collections the information is saved and will be inserted in the corresponding tables after the forms are submitted.
Now one column in the table has remained empty and I am not sure how to solve it in APEX.
Namely, the table has a foreign key to another table.
But the ID of this table is generated only after submitting the forms.
Can I solve it, for example, with a trigger that then enters the foreign key into the table after the forms are submitted?
Would it be an after insert trigger like this:
CREATE OR REPLACE TRIGGER INSERT_FK
AFTER INSERT
ON TBL1
FOR EACH ROW
begin
INSERT INTO TBL2
VALUES (:NEW.STUID);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.put_line (TO_CHAR (SQLERRM (-20299)));
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (TO_CHAR (SQLERRM (-20298)));
end;
or is there another better solution for this?
I would not use a trigger for that, but handle this in your application.
You can achieve this by using the RETURNING INTO clause. That allows you to reuse the value of an inserted column in the same transaction.If this is in an anonymous pl/sql block in a page process it would be something like this:
DECLARE
l_id table1.id%TYPE;
BEGIN
INSERT INTO table1(val) VALUES ('Europe')
RETURNING id INTO l_id;
INSERT INTO table2(continent_id, val) VALUES (l_id,'Belgium');
END;
/
In an apex form, you have an option to return the primary key into a page item after insert/update so you can use it in other processes if you use the built-in form processing.
This won't work; you'd insert only the :new.stuid column value into TBL2 which "might" succeed (if other columns in tbl2 aren't NOT NULL), but - all other columns will remain empty.
I guess you should prepare all data while you're still in Apex (i.e. fetch primary key for tbl1 and - at the same time - use it as a foreign key value for tbl2). Otherwise, there's no way to populate that information later because there's no other relation between these two tables (if there were, you wouldn't need the foreign key column, would you?).

updating partition Key, row movement not allowed

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

Add a auto increment primary key to existing table in oracle [duplicate]

This question already has answers here:
How to create id with AUTO_INCREMENT on Oracle?
(18 answers)
Closed 7 years ago.
I want to add a new auto increment primary column to a existing table which has data. How do I do that?
I first added a column and then try to add a sequence after that, I lost how to insert and make that column as primary key.
Say your table is called t1 and your primary-key is called id
First, create the sequence:
create sequence t1_seq start with 1 increment by 1 nomaxvalue;
Then create a trigger that increments upon insert:
create trigger t1_trigger
before insert on t1
for each row
begin
select t1_seq.nextval into :new.id from dual;
end;
If you have the column and the sequence, you first need to populate a new key for all the existing rows. Assuming you don't care which key is assigned to which row
UPDATE table_name
SET new_pk_column = sequence_name.nextval;
Once that's done, you can create the primary key constraint (this assumes that either there is no existing primary key constraint or that you have already dropped the existing primary key constraint)
ALTER TABLE table_name
ADD CONSTRAINT pk_table_name PRIMARY KEY( new_pk_column )
If you want to generate the key automatically, you'd need to add a trigger
CREATE TRIGGER trigger_name
BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
:new.new_pk_column := sequence_name.nextval;
END;
If you are on an older version of Oracle, the syntax is a bit more cumbersome
CREATE TRIGGER trigger_name
BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
SELECT sequence_name.nextval
INTO :new.new_pk_column
FROM dual;
END;
Snagged from Oracle OTN forums
Use alter table to add column, for example:
alter table tableName add(columnName NUMBER);
Then create a sequence:
CREATE SEQUENCE SEQ_ID
START WITH 1
INCREMENT BY 1
MAXVALUE 99999999
MINVALUE 1
NOCYCLE;
and, the use update to insert values in column like this
UPDATE tableName SET columnName = seq_test_id.NEXTVAL
You can use the Oracle Data Modeler to create auto incrementing surrogate keys.
Step 1. - Create a Relational Diagram
You can first create a Logical Diagram and Engineer to create the Relational Diagram or you can straightaway create the Relational Diagram.
Add the entity (table) that required to have auto incremented PK, select the type of the PK as Integer.
Step 2. - Edit PK Column Property
Get the properties of the PK column.
You can double click the name of the column or click on the 'Properties' button.
Column Properties dialog box appears.
Select the General Tab (Default Selection for the first time).
Then select both the 'Auto Increment' and 'Identity Column' check boxes.
Step 3. - Additional Information
Additional information relating to the auto increment can be specified by selecting the 'Auto Increment' tab.
Start With
Increment By
Min Value
Max Value
Cycle
Disable Cache
Order
Sequence Name
Trigger Name
Generate Trigger
It is usually a good idea to mention the sequence name, so that it will be useful in PL/SQL.
Click OK (Apply) to the Column Properties dialog box.
Click OK (Apply) to the Table Properties dialog box.
Table appears in the Relational Diagram.

Insert into oracle database

Hi I have a database with loads of columns and I want to insert couple of records for testing, now in order to insert something into that database I'd have to write large query .. is it possible to do something like this
INSERT INTO table (SELECT FROM table WHERE id='5') .. I try to insert the row with ID 5 but I think this will create a problem because it will try to duplicate a record, is it possible to change this ID 5 to let say 1000 then I'd be able to insert data without writing complex query and while doing so avoiding replication of data .. tnx
In PL/SQL you can do something like this:
declare
l_rec table%rowtype;
begin
select * into l_rec from table where id='5';
l_rec.id := 1000;
insert into table values l_rec;
end;
If you have a trigger on the table to handle the primary key from a sequence (:NEW.id = seq_sequence.NEXTVAL) then you should be able to do:
INSERT INTO table
(SELECT columns_needed FROM table WHERE whatever)
This will allow you to add in many rows at one (the number being limited by the WHERE clause). You'll need to select the columns that are required by the table to be not null or not having default values. Beware of any unique constraints as well.
Otherwise you'll be looking at PL/SQL or some other form of script to insert multiple rows.
For each column that has no default value or you want to insert the values other than default, you will need to provide the explicit name and value.
You only can use an implicit list (*) if you want to select all columns and insert them as they are.
Since you are changing the PRIMARY KEY, you need to enumerate.
However, you can create a before update trigger and change the value of the PRIMARY KEY in this trigger.
Note that the trigger cannot reference the table itself, so you will need to provide some other way to get the unique number (like a sequence):
CREATE TRIGGER trg_mytable_bi BEFORE INSERT ON mytable FOR EACH ROW
BEGIN
:NEW.id := s_mytable.nextval;
END;
This way you can use the asterisk but it will always replace the value of the PRIMARY KEY.

Assign auto-incrementing value to new column in Oracle

I have this table in an Oracle DB which has a primary key defined on 3 of the data columns. I want to drop the primary key constraint to allow rows with duplicate data for those columns, and create a new column, 'id', to contain an auto-incrementing integer ID for these rows. I know how to create a sequence and trigger to add an auto-incrementing ID for new rows added to the table, but is it possible to write a PL/SQL statement to add unique IDs to all the rows that are already in the table?
Once you have created the sequence:
update mytable
set id = mysequence.nextval;
If you're just using an integer for a sequence you could update the id with the rownum. e.g.
update
table
set id = rownum
You then need to reset the sequence to the next valid id.
Is this what you need?
UPDATE your_table
SET id = your_seq.nextval;
This assumes you don't care what order your primary keys are in.
First you should check your PCTFREE... is there enough room for every row to get longer?
If you chose a very small PCTFREE or your data has lots of lenght-increasing updates, you might begin chaining every row to do this as an update.
You almost certainly better to do this as a CTAS.
Create table t2 as select seq.nextval, t1.* from t1.
drop t1
rename t2 to t1.

Resources