我有这张桌子:
XPTO_TABLE (id, obj_x, date_x, type_x, status_x)
我想创建一个仅在(obj_x, date_x, type_x)
时才适用于字段status_x <> 5
的唯一约束。
我试图创建这个,但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));
正确的语法是什么?
答案 0 :(得分:16)
@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);
希望有所帮助
Vishad
答案 1 :(得分:5)
在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.
答案 2 :(得分:2)
因为CREATE UNIQUE 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));
答案 3 :(得分:0)
CREATE UNIQUE INDEX UN_MYID_uniq_IDX
ON MYTABLE(
(CASE
WHEN MY_id > 1428923
THEN MY_INDEX_COLUMN
ELSE
NULL
END));
如果 MY_INDEX_COLUMN
大于 my_id
,1428923
值不能重复。