2011-11-30 19 views
11

Nunca antes había creado un disparador en Oracle, así que estoy buscando una dirección.Activador de Oracle para crear un autonumber

Me gustaría crear un disparador que incremente un ID en uno si el ID no está en la instrucción de inserción.

La ID debe comenzar en 10000, y cuando se inserta un registro, la siguiente ID debe ser 10001. Si la instrucción de inserción contiene una ID, debe anular el incremento automático.

es decir

insert into t1 (firstname, lastname) values ('Michael','Jordan'),('Larry','Bird') 

debe verse como:

nombre apellido Identificación

Micahel Jordan 10000

Larry Bird 10001

insert into t1 (firstname, lastname, id) values ('Scottie','Pippen',50000) 

debe ser similar:

Identificación del nombre apellido

Micahel Jordan 10000

Larry Bird 10001

Scottie Pippen 50000

Respuesta

24

Algo como esto funcionará en 11g

CREATE SEQUENCE t1_id_seq 
    start with 10000 
    increment by 1; 

CREATE TRIGGER trigger_name 
    BEFORE INSERT ON t1 
    FOR EACH ROW 
DECLARE 
BEGIN 
    IF(:new.id IS NULL) 
    THEN 
    :new.id := t1_id_seq.nextval; 
    END IF; 
END; 

Si está en una versión anterior sión, tendrá que hacer un SELECT INTO para obtener el siguiente valor de la secuencia

CREATE TRIGGER trigger_name 
    BEFORE INSERT ON t1 
    FOR EACH ROW 
DECLARE 
BEGIN 
    IF(:new.id IS NULL) 
    THEN 
    SELECT t1_id_seq.nextval 
     INTO :new.id 
     FROM dual; 
    END IF; 
END; 

Tenga en cuenta que las secuencias de Oracle no están libres de brecha. Por lo tanto, es muy posible que los valores particulares se omitan por una variedad de razones. Su primer inserto puede tener una ID de 10000 y el segundo puede tener una ID de 10020 si se realiza en minutos, horas o días después.

Además, tenga en cuenta que Oracle no admite la especificación de varias filas en la cláusula VALUES como lo hace MySQL. Así que en lugar de

insert into t1 (firstname, lastname) values ('Michael','Jordan'),('Larry','Bird') 

se necesitaría dos instrucciones INSERT separados

insert into t1 (firstname, lastname) values ('Michael','Jordan'); 
insert into t1 (firstname, lastname) values ('Larry','Bird'); 
+0

[https://github.com/miklagard/oracle-table-creator](https://github.com/miklagard/oracle-table-creator) – cem

2

recomendaría a codificar esta gatillo con una condición en el propio gatillo, no en el bloque de SQL.

CREATE OR REPLACE TRIGGER your_trigger 
BEFORE INSERT ON your_table 
REFERENCING NEW AS NEW OLD AS OLD 
FOR EACH ROW 
WHEN (new.id IS NULL) 
    BEGIN 
    SELECT your_sequence.nextval 
    INTO :new.id 
    FROM dual; 
    END; 
/

Con esta solución, el disparador solo se ejecuta si la condición coincide (id es nulo).

De lo contrario, el activador siempre se ejecuta y el bloque comprueba si id es nulo. El DB debe ejecutar el bloque SQL que no hace nada en valores nulos.

Cuestiones relacionadas