Oracle数据库中多个字段的条件唯一约束

kkih6yb8  于 2023-10-16  发布在  Oracle
关注(0)|答案(4)|浏览(136)

我有这张table:

XPTO_TABLE (id, obj_x, date_x, type_x, status_x)

我想创建一个唯一的约束,仅当status_x <> 5时才应用于字段(obj_x, date_x, type_x)
我试着创建这个,但Oracle说:

line 1: ORA-00907: missing right parenthesis
CREATE UNIQUE INDEX UN_OBJ_DT_TYPE_STATUS
ON XPTO_TABLE(
    (CASE
         WHEN STATUS_X <> 5
         THEN
             (OBJ_X,
              TO_CHAR (DATE_X, 'dd/MM/yyyy'),
              TYPE_X)
         ELSE
             NULL
     END));

正确的语法是什么?

3ks5zfa0

3ks5zfa01#

@jamesfrj:看起来你试图确保你的表只包含一条status <>5的记录。
您可以尝试通过连接列来创建唯一的函数索引,如下所示

create table XPTO_TABLE (id number, 
                            obj_x varchar2(20),
                            date_x date,
                            type_x varchar2(20),
                            status_x varchar2(20)                              
                           );

      create unique index xpto_table_idx1 on XPTO_TABLE(case when status_x <>'5'  THEN              obj_x||date_x||type_x||STATUS_x ELSE null END);
vnzz0bqm

vnzz0bqm2#

在Oracle 11下,你可以创建一堆只有当STATUS_X为5时才获得非NULL值的虚拟列,然后使 * 它们 * 唯一:

CREATE TABLE XPTO_TABLE (
  ID INT PRIMARY KEY,
  OBJ_X INT,
  DATE_X DATE,
  TYPE_X VARCHAR2(50),
  STATUS_X INT,
  OBJ_U AS (CASE STATUS_X WHEN 5 THEN OBJ_X ELSE NULL END),
  DATE_U AS (CASE STATUS_X WHEN 5 THEN DATE_X ELSE NULL END),
  TYPE_U AS (CASE STATUS_X WHEN 5 THEN TYPE_X ELSE NULL END),
  UNIQUE (OBJ_U, DATE_U, TYPE_U)
);

您可以自由插入重复项,只要STATUS_X为不为5:

INSERT INTO XPTO_TABLE (ID, OBJ_X, DATE_X, TYPE_X, STATUS_X) VALUES (1, 1, '1-JAN-2014', 'foo', 4);
INSERT INTO XPTO_TABLE (ID, OBJ_X, DATE_X, TYPE_X, STATUS_X) VALUES (2, 1, '1-JAN-2014', 'foo', 4);

但是当STATUS_X为5时,尝试插入副本失败:

INSERT INTO XPTO_TABLE (ID, OBJ_X, DATE_X, TYPE_X, STATUS_X) VALUES (3, 1, '1-JAN-2014', 'foo', 5);
INSERT INTO XPTO_TABLE (ID, OBJ_X, DATE_X, TYPE_X, STATUS_X) VALUES (4, 1, '1-JAN-2014', 'foo', 5);

Error report -
SQL Error: ORA-00001: unique constraint (IFSAPP.SYS_C00139498) violated
00001. 00000 -  "unique constraint (%s.%s) violated"
*Cause:    An UPDATE or INSERT statement attempted to insert a duplicate key.
           For Trusted Oracle configured in DBMS MAC mode, you may see
           this message if a duplicate entry exists at a different level.
*Action:   Either remove the unique restriction or do not insert the key.
cotxawn7

cotxawn73#

由于CREATEUNIQUE INDEX只需要一个值,因此可以按如下方式连接列

CREATE UNIQUE INDEX UN_OBJ_DT_TYPE_STATUS
ON XPTO_TABLE(
(CASE
     WHEN STATUS_X <> 5
         THEN OBJ_X || TO_CHAR (DATE_X, 'dd/MM/yyyy') || TYPE_X
     ELSE
         NULL
 END));
mjqavswn

mjqavswn4#

CREATE UNIQUE INDEX UN_MYID_uniq_IDX
ON MYTABLE(
(CASE
     WHEN MY_id > 1428923
         THEN MY_INDEX_COLUMN
     ELSE
         NULL
 END));

如果my_id大于1428923,则MY_INDEX_COLUMN值不能重复。

相关问题