Using sequential values for the primary key in an INSERT query - oracle

How can I write an insert query for an Oracle database which has a sequential primary key so that the insert statement automatically takes the next number in the sequence?
INSERT INTO LD_USER_ROLE(USER_ROLE_ID,INS_USER,INS_DATE, USERNAME)
VALUES (100, 'sp22',to_date('2003/05/03 21:02:44','yyyy/mm/dd hh24:mi:ss'),'JOHN BARRY', )
In the above statement I have hardcoded the value of 100 for the key 'USER_ROLE_ID' but I'd like to alter this as explained in the first paragraph.

Why don't you just create a trigger for your sequence like this:
Sequence:
CREATE SEQUENCE LD_USER_ROLE_SEQ
INCREMENT BY 1 START WITH 1 NOMAXVALUE NOMINVALUE NOCYCLE NOCACHE NOORDER
Trigger:
CREATE TRIGGER LD_USER_ROLE_INSERT BEFORE INSERT ON LD_USER_ROLE
REFERENCING NEW AS NEW OLD AS OLD FOR EACH ROW
BEGIN
SELECT LD_USER_ROLE_SEQ.NEXTVAL INTO :NEW.USER_ROLE_ID FROM DUAL;
END;
The trigger will automatically get the next value/id on every insert (like auto_increment in mysql).

Apart from using a trigger, you can use a sequence directly in the insert statement:
CREATE SEQUENCE LD_USER_ROLE_SEQ;
INSERT INTO LD_USER_ROLE
(USER_ROLE_ID,INS_USER,INS_DATE, USERNAME)
VALUES
(ld_user_role_seq.nextval, 'sp22',to_date('2003/05/03 21:02:44','yyyy/mm/dd hh24:mi:ss'),'JOHN BARRY', )

Related

Insert in Merge not working in Oracle

I am new to Oracle. I have a table in Oracle which has 4 columns Period, Open_Flag,Creation_Dt,Updated_By.
The Period column is the Primary key of the table. I have created a proc which will check the value of period from input parameter in the table, if its existing, the value of Open_flag has to be updated else a new record shall be inserted.
create or replace
PROCEDURE PROC_REF_SAP_PERIOD(
V_PERIOD IN NUMBER,V_OPEN_FLAG IN VARCHAR2,V_CREATION_DT IN DATE,V_UPDATED_BY IN VARCHAR2)
AS
BEGIN
MERGE INTO REF_SAP_PERIOD T
USING (SELECT * FROM REF_SAP_PERIOD WHERE PERIOD=V_PERIOD )S
ON (T.PERIOD=S.PERIOD )
WHEN MATCHED THEN UPDATE SET OPEN_FLAG = V_OPEN_FLAG --WHERE PERIOD=V_PERIOD AND CREATION_DT=V_CREATION_DT AND UPDATED_BY=V_UPDATED_BY
WHEN NOT MATCHED THEN INSERT (PERIOD,OPEN_FLAG,CREATION_DT,UPDATED_BY) VALUES (V_PERIOD,V_OPEN_FLAG,V_CREATION_DT,V_UPDATED_BY);
END;
The issue is that the Update is working well in this case, however, the insert is not working. Please help.
You are merging table with itself, filtered by period. Obviously, it will never see your non-existent values in itself.
Try this line instead of your USING line:
using (select V_PERIOD "period" from dual)S

Difference between Oracle sequence last number and max id inserted

I'm working on a application used by multiple users. They can insert, delete and update rows in the database which fires triggers what write into log tables. The problem is that the difference between the maximum id inserted in the log table and the last number generated by the sequences used by the trigger is changing continously. Sometimes an primary key exception is generated because the the sequence generate values that are already inserted in the table.
CREATE OR REPLACE
TRIGGER EVALUACION.TCALIF_DEL
AFTER DELETE ON EVALUACION.CALIFICACIONES FOR EACH ROW
BEGIN
INSERT INTO LOG_CALIFICACIONES (ID_BITACORA, ID_EVALUACION, ANIO, CALIFICACION, OBSERVACION, USUARIO, FECHA_HORA, TIPO_OPERACION_BD)
SELECT SEQ_CALIF.NEXTVAL, :OLD.ID_EVALUACION, :OLD.ANIO, :OLD.CALIFICACION, :OLD.OBSERVACION, :OLD.USUARIO, :OLD.FECHA_HORA, 'D' FROM DUAL;
END;
CREATE OR REPLACE
TRIGGER EVALUACION.TCALIF_INS
AFTER INSERT ON EVALUACION.CALIFICACIONES FOR EACH ROW
BEGIN
INSERT INTO LOG_CALIFICACIONES (ID_BITACORA, ID_EVALUACION, ANIO, CALIFICACION, OBSERVACION, USUARIO, FECHA_HORA, TIPO_OPERACION_BD)
SELECT SEQ_CALIF.NEXTVAL, :OLD.ID_EVALUACION, :OLD.ANIO, :OLD.CALIFICACION,:OLD.OBSERVACION, :OLD.USUARIO, :OLD.FECHA_HORA, 'I' FROM DUAL;
END;
CREATE OR REPLACE
TRIGGER EVALUACION2010.TCALIF_UPD
AFTER UPDATE ON EVALUACION.CALIFICACIONES FOR EACH ROW
BEGIN
INSERT INTO LOG_CALIFICACIONES (ID_BITACORA, ID_EVALUACION, ANIO, CALIFICACION, OBSERVACION, USUARIO, FECHA_HORA, TIPO_OPERACION_BD)
SELECT SEQ_CALIF.NEXTVAL, :OLD.ID_EVALUACION, :OLD.ANIO, :OLD.CALIFICACION, :OLD.OBSERVACION, :OLD.USUARIO, :OLD.FECHA_HORA, 'U' FROM DUAL; END;
The code for the sequence is:
CREATE SEQUENCE "EVALUACION"."SEQ_CALIF"
MINVALUE 1
MAXVALUE 999999999999999999999999999
INCREMENT BY 1
START WITH 11114992
CACHE 20
NOORDER
NOCYCLE
NOPARTITION;

insert multiple row into table using select however table has primery key in oracle SQL [duplicate]

This question already has answers here:
How to create id with AUTO_INCREMENT on Oracle?
(18 answers)
Closed 8 years ago.
I am facing issue while inserting multiple row in one go into table because column id has primary key and its created based on sequence.
for ex:
create table test (
iD number primary key,
name varchar2(10)
);
insert into test values (123, 'xxx');
insert into test values (124, 'yyy');
insert into test values (125, 'xxx');
insert into test values (126, 'xxx');
The following statement creates a constraint violoation error:
insert into test
(
select (SELECT MAX (id) + 1 FROM test) as id,
name from test
where name='xxx'
);
This query should insert 3 rows in table test (having name=xxx).
You're saying that your query inserts rows with primary key ID based on a sequence. Yet, in your insert/select there is select (SELECT MAX (id) + 1 FROM test) as id, which clearly is not based on sequence. It may be the case that you are not using the term "sequence" in the usual, Oracle way.
Anyway, there are two options for you ...
Create a sequence, e.g. seq_test_id with the starting value of select max(id) from test and use it (i.e. seq_test_id.nextval) in your query instead of the select max(id)+1 from test.
Fix the actual subselect to nvl((select max(id) from test),0)+rownum instead of (select max(id)+1 from test).
Please note, however, that the option 2 (as well as your original solution) will cause you huge troubles whenever your code runs in multiple concurrent database sessions. So, option 1 is strongly recommended.
Use
insert into test (
select (SELECT MAX (id) FROM test) + rownum as id,
name from test
where name='xxx'
);
as a workaround.
Of course, you should be using sequences for integer-primary keys.
If you want to insert an ID/Primary Key value generated by a sequence you should use the sequence instead of selecting the max(ID)+1.
Usually this is done using a trigger on your table wich is executed for each row. See sample below:
CREATE TABLE "MY_TABLE"
(
"MY_ID" NUMBER(10,0) CONSTRAINT PK_MY_TABLE PRIMARY KEY ,
"MY_COLUMN" VARCHAR2(100)
);
/
CREATE SEQUENCE "S_MY_TABLE"
MINVALUE 1 MAXVALUE 999999999999999999999999999
INCREMENT BY 1 START WITH 10 NOCACHE ORDER NOCYCLE NOPARTITION ;
/
CREATE OR REPLACE TRIGGER "T_MY_TABLE"
BEFORE INSERT
ON
MY_TABLE
REFERENCING OLD AS OLDEST NEW AS NEWEST
FOR EACH ROW
WHEN (NEWEST.MY_ID IS NULL)
DECLARE
IDNOW NUMBER;
BEGIN
SELECT S_MY_TABLE.NEXTVAL INTO IDNOW FROM DUAL;
:NEWEST.MY_ID := IDNOW;
END;
/
ALTER TRIGGER "T_MY_TABLE" ENABLE;
/
insert into MY_TABLE (MY_COLUMN) values ('DATA1');
insert into MY_TABLE (MY_COLUMN) values ('DATA2');
insert into MY_TABLE (MY_ID, MY_COLUMN) values (S_MY_TABLE.NEXTVAL, 'DATA3');
insert into MY_TABLE (MY_ID, MY_COLUMN) values (S_MY_TABLE.NEXTVAL, 'DATA4');
insert into MY_TABLE (MY_COLUMN) values ('DATA5');
/
select * from MY_TABLE;

Trigger required to insert data [duplicate]

This question already has answers here:
Using sequential values for the primary key in an INSERT query
(2 answers)
Closed 9 years ago.
I am trying to load a column with unique sequence number each time a row of data is insrerted in the table.How can this be achieved?
You can create a Sequence, and then use the sequence nextval in your insert statements for the column which you want to have sequential incremented value.
CREATE SEQUENCE seq
INCREMENT BY 1
START WITH 1
NOMAXVALUE
NOCYCLE
CACHE 10;
INSERT INTO tab VALUES (seq.nextval, col1, col2, col3);
there is nothing like "auto_increment" or "identity" in Oracle,
but if you want auto increment in your column value you can use Sequence for the this.
after creating sequence you can use After Insert Trigger to insert identical value.
here is trigger example...
CREATE OR REPLACE TRIGGER dep_ins_trig
BEFORE INSERT ON <table_name>
FOR EACH ROW
BEGIN
SELECT dept_seq.NEXTVAL
INTO :new.id
FROM dual;
END;
/
This is achieved by Trigger and Sequence when you want serialized number that anyone can easily read/remember/understand. But if you don't want to manage ID Column (like emp_id) by this way, and value of this column is not much considerable, you can use SYS_GUID() at Table Creation to get Auto Increment like this.
CREATE TABLE <table_name>
(emp_id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
name VARCHAR2(30));
Now your emp_id column will accept "globally unique identifier value".
you can insert value in table by ignoring emp_id column like this.
INSERT INTO <table_name> (name) VALUES ('name value');
So, it will insert unique value to your emp_id Column.

Truncate data and if insert new row column increment from 1

I have table with two rows which one ID with auto increment and there are much row last number ID is 89. And then I truncate data/row in the table. And then I insert row again.
But number ID from 90 not from 1 (one). If in mysql if I truncate data in table auto increment start from 1 (one) again. So how in oracle I want to ID autoincrement from one again. Thanx.
Below step when I create table:
// create table;
CREATE TABLE tes (
id NUMBER NULL,
ip_address varchar2(25) NOT NULL
PRIMARY KEY (id)
);
// and create increment;
CREATE SEQUENCE tes_sequence START WITH 1 INCREMENT BY 1;
// and create trigger;
CREATE OR REPLACE TRIGGER tes_trigger
BEFORE INSERT
ON tes
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT tes_sequence.nextval INTO :NEW.ID FROM dual;
END;
Oracle sequence is a separate object and is not connected with table. If you need to start sequence after truncating a table you need to alter the sequence. Have a look here: How do I reset a sequence in Oracle?

Resources