2011-01-10 13 views
8

¿Soporta Oracle restricciones con expresiones como tal?Restricción única de Oracle con Expresión

Aviso Z = 'N'

ALTER TABLE A ADD CONSTRAINT U_A_KEY UNIQUE(X,Y,Z = 'N'); 

¿Es esta Unique constraint posible?

Ejemplo:

INSERT INTO A VALUES('X','Y','N'); --OK 
INSERT INTO A VALUES('X','Y','Y'); --OK 
INSERT INTO A VALUES('X','Y','Y'); --OK 
INSERT INTO A VALUES('X','Y','N'); --VOLIATION 
+0

¿Eso significa que quiere tener como máximo un registro con Z = 'N' para cada combinación x, y? –

+0

Sí, eso es correcto. – JamesC

Respuesta

18

Tal vez esto da una idea

drop table tq84_n; 

create table tq84_n (
    x number, 
    y number, 
    z varchar2(10) 
); 

create unique index tq84_n_x on tq84_n (
    case when z = 'N' then x || '-' || y 
     else null 
    end 
); 

después:

insert into tq84_n values (4,5, 'N'); 

insert into tq84_n values (9,6, 'Y'); 
insert into tq84_n values (9,6, 'Y'); 

insert into tq84_n values (4,5, 'Y'); 

insert into tq84_n values (4,5, 'N'); 

El último lanza:

ORA-00001: unique constraint (SPEZMDBA.TQ84_N_X) violated 
+0

Eso cumple con el caso de uso, gracias por la sugerencia. – JamesC

+1

+1 para mostrar la violación de restricción. –

6

El enfoque más simple en este caso es en general para crear un índice basado función. Algo así como

CREATE UNIQUE INDEX u_a_key 
    ON a((CASE WHEN z = 'N' THEN x ELSE null END), 
      (CASE WHEN z = 'N' THEN y ELSE null END)); 

Si z no es 'N', ambas sentencias CASE evaluar a NULL y Oracle no tiene que almacenar los valores de x & Y en la estructura del índice (haciendo el menor índice). Si z es 'N', los valores de x & y se almacenan en el índice y el índice se comporta como cualquier otro índice compuesto.

0

Lo que hago en que sitaution es crear una columna, por ejemplo, Z en su caso, que tiene:

  • Un valor particular (por ejemplo, su "N") en el caso que lo necesite que ser único
  • Null de otra manera, lo que significa desconocido: dos valores desconocidos se consideran no iguales el uno al otro.

Luego puede crear su restricción única UNIQUE(X,Y,Z).

Agregue dos filas con igual X, Y y Z = "N" y obtendrá un error; agrega dos filas con igual X e Y, ambas con Z = nulo y no lo harás.

+0

La columna Z puede contener otro valor que debe superar la restricción. Pregunta actualizada con SQL para aclarar, gracias. – JamesC

Cuestiones relacionadas