Db2 在一列可为空的多列上强制执行唯一关系
给定桌子Db2 在一列可为空的多列上强制执行唯一关系,db2,db2-400,unique-index,Db2,Db2 400,Unique Index,给定桌子 ID PERSON_ID PLAN EMPLOYER_ID TERMINATION_DATE 1 123 ABC 321 2020-01-01 2 123 DEF 321 (null) 3 123 ABC 321 (null) 4 123 ABC 321
ID PERSON_ID PLAN EMPLOYER_ID TERMINATION_DATE
1 123 ABC 321 2020-01-01
2 123 DEF 321 (null)
3 123 ABC 321 (null)
4 123 ABC 321 (null)
我想排除第四个条目。(第三个条目显示此人已被重新雇用,因此是新的关系。我只显示相关字段)
我的第一次尝试是简单地在个人ID/计划/雇主ID/终止日期
上创建一个唯一索引,认为DB2forIBMI认为空值在唯一索引中是相等的。我显然错了
编辑 根据7.3的文件: 独特的 防止表包含具有相同索引键值的两行或多行使用UNIQUE时,一列的所有空值都被视为相等。例如,如果键是可以包含空值的单个列,则该列只能包含一个空值。当更新表的行或插入新行时,强制执行该约束。 在执行CREATEINDEX语句期间,还将检查约束。如果表中已包含具有重复键值的行,则不会创建索引 唯一,其中不为NULL 防止表包含具有相同索引键值的两行或多行,其中列的所有空值都不相等。一列中允许有多个空值。否则,这与UNIQUE相同 所以,我看到的行为看起来更像是唯一的,而不是NULL。当我为这个表生成SQL时,我看到
ADD CONSTRAINT TERMEMPPLANSSN
UNIQUE( TERMINATION_DATE , EMPLOYERID , PLAN_CODE , SSN ) ;
(注意,这显示的是真实的字段名,而不是我在示例中使用的字段名)
编辑2 底线,约束!==指数当我返回并创建一个实际的索引时,我得到了所需的行为
CREATE TABLE PERSON
(
ID INT NOT NULL
, PERSON_ID INT NOT NULL
, PLAN CHAR(3) NOT NULL
, EMPLOYER_ID INT
, TERMINATION_DATE DATE
);
INSERT INTO PERSON (ID, PERSON_ID, PLAN, EMPLOYER_ID, TERMINATION_DATE)
VALUES
(1, 123, 'ABC', 321, DATE('2020-01-01'))
, (2, 123, 'DEF', 321, CAST(NULL AS DATE))
, (3, 123, 'ABC', 321, CAST(NULL AS DATE))
WITH NC;
---不允许:---
你可以:
CREATE UNIQUE INDEX PERSON_U1 ON PERSON
(PERSON_ID, PLAN, EMPLOYER_ID, TERMINATION_DATE);
CREATE UNIQUE WHERE NOT NULL INDEX PERSON_U2 ON PERSON
(PERSON_ID, PLAN, EMPLOYER_ID, TERMINATION_DATE);
---不允许:---
但允许多个:
(X, 123, 'ABC', 321, CAST(NULL AS DATE))
(Y, 123, 'ABC', 321, CAST(NULL AS DATE))
...
你可以:
CREATE UNIQUE INDEX PERSON_U1 ON PERSON
(PERSON_ID, PLAN, EMPLOYER_ID, TERMINATION_DATE);
CREATE UNIQUE WHERE NOT NULL INDEX PERSON_U2 ON PERSON
(PERSON_ID, PLAN, EMPLOYER_ID, TERMINATION_DATE);
您的DB2forIBMi版本是什么?我的7.4不允许我在
(个人ID、计划、雇主ID、终止日期)
:SQLCODE=-803
上插入第4条记录和现有的第3条记录和唯一索引。我认为这是V7R3M0版本。规则必须与7.3相同。请提供一个包含可空列的唯一索引的可复制示例,该索引允许一列中有多个空,而其他列的值相同。@MarkBarinstein感谢您的关注。如果表格已经包含1-3行,您是否需要比我刚才添加的更多的内容?我得到了您的要求“排除第4项”,因为要求不允许插入第4行(终止日期为空)。表中已经存在具有相同列值的第3行,因此,惟一索引(非惟一约束-DB2不允许对可为null的列进行惟一约束)应该满足这样的要求UNIQUE,其中NOT NULL
允许您仅控制NOT NULL值的唯一性。也就是说,它阻止您插入另一行终止日期='2020-01-01'
,其他3行的列值与第一行相同。