I have a table with wrong data and I'd like to prevent new wrong data from being inserted while I fix data and find out what process or where is the sentence making this happen. I first made a UQ constraint over the columns that shouldn't be duplicated, but this gets me into another problem: I need to apply uniqueness only when all the columns have value, if there are nulls I need duplicate records over these columns. Something like this:
CREATE TABLE MYTAB (COL1 NUMBER, COL2 NUMBER, COL3 NUMBER, COL4 NUMBER); --EXAMPLE TABLE. I NEED NO DUPS OVER (COL1, COL3, COL4)
INSERT INTO MYTAB VALUES (1, 1, 1, 1); --OK
INSERT INTO MYTAB VALUES (1, 2, 1, 1); -- NOOK
INSERT INTO MYTAB VALUES (1, 3, NULL, NULL); --OK
INSERT INTO MYTAB VALUES (1, 4, NULL, NULL); --OK
If I create a constraint like this:
ALTER TABLE MYTAB
ADD CONSTRAINT U_CONSTRAINT UNIQUE (COL1, COL3, COL4) NOVALIDATE;
Last insert will crash.
I've tried with
CREATE UNIQUE INDEX FN_UIX_MYTAB
ON MYTAB (CASE WHEN COL2 IS NOT NULL THEN COL1 ELSE null END,
CASE WHEN COL2 IS NOT NULL THEN COL3 ELSE null END
CASE WHEN COL2 IS NOT NULL THEN COL4 ELSE null END) ;
But the create crashes because table has duplicate data. I'll need to create this index without validating existing data, which means index will be applied only to new records inserted.
I've tried also with:
CREATE INDEX FN_IX_MYTAB
ON MYTAB (CASE WHEN COL2 IS NOT NULL THEN COL1 ELSE null END,
CASE WHEN COL2 IS NOT NULL THEN COL3 ELSE null END,
CASE WHEN COL2 IS NOT NULL THEN COL4 ELSE null END) ;
ALTER TABLE MYTAB
ADD CONSTRAINT FN_UIX_MYTAB UNIQUE (COL1, COL3, COL4) USING INDEX FN_IX_MYTAB NOVALIDATE;
But this gives me error:
ORA-14196: Specified index cannot be used to enforce the constraint.
Is there a way to do what I've explained, or should I prevent wrong inserts in another way while I look for the origin of the problem? Any advice will be appreciated also.