Saltar al contenido

Insertar si no existe Oracle

Recuerda que en las ciencias informáticas un error casi siempere puede tener más de una resoluciones, por lo tanto nosotros aquí te enseñaremos lo más óptimo y eficiente.

Solución:

Llegar tarde a la fiesta, pero…

Con Oracle 11.2.0.1 hay un pista semántica que puede hacer esto: IGNORE_ROW_ON_DUPKEY_INDEX

Ejemplo:

insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(customer_orders,pk_customer_orders) */
  into customer_orders
       (order_id, customer, product)
values (    1234,     9876,  'K598')
     ;

ACTUALIZAR: aunque esta sugerencia funciona (si la deletrea correctamente), hay mejores enfoques que no requieren Oracle 11R2:

Primer enfoque: traducción directa de la sugerencia semántica anterior:

begin
  insert into customer_orders
         (order_id, customer, product)
  values (    1234,     9876,  'K698')
  ;
  commit;
exception
  when DUP_VAL_ON_INDEX
  then ROLLBACK;
end;

Segundo enfoque: un lote más rápido que las dos sugerencias anteriores cuando hay mucha disputa:

begin
    select count (*)
    into   l_is_matching_row
    from   customer_orders
    where  order_id = 1234
    ;

    if (l_is_matching_row = 0)
    then
      insert into customer_orders
             (order_id, customer, product)
      values (    1234,     9876,  'K698')
      ;
      commit;
    end if;
exception
  when DUP_VAL_ON_INDEX
  then ROLLBACK;
end;

La sentencia se llama MERGE. Búscalo, soy demasiado perezoso.

Sin embargo, tenga en cuenta que MERGE no es atómico, lo que podría causar el siguiente efecto (gracias, Marius):

SESS1:

create table t1 (pk int primary key, i int);
create table t11 (pk int primary key, i int);
insert into t1 values(1, 1);
insert into t11 values(2, 21);
insert into t11 values(3, 31);
commit;

SES2: insert into t1 values(2, 2);

SESS1:

MERGE INTO t1 d
USING t11 s ON (d.pk = s.pk)
WHEN NOT MATCHED THEN INSERT (d.pk, d.i) VALUES (s.pk, s.i);

SES2: commit;

SESS1: ORA-00001

Esto solo se inserta si el elemento que se va a insertar aún no está presente.

Funciona igual que:

if not exists (...) insert ... 

en TSQL

insert into destination (DESTINATIONABBREV) 
  select 'xyz' from dual 
  left outer join destination d on d.destinationabbrev = 'xyz' 
  where d.destinationid is null;

Puede que no sea bonito, pero es útil 🙂

Acuérdate de que tienes el privilegio decir .

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *