关系数据库检查约束ORACLE
Relational Databases Check Constraint ORACLE
我正在为 Uni 做一个项目,我对数据库没有太多的了解或经验。我正在尝试在 Oracle 中使用 table 创建一个数据库,其中包含可以是 2 种类型的制造零件,比如 1 和 2。当零件是类型 1 时,我将在 table 中存储它位置,当它是类型 2 时,我将在相同的 table 中存储提前期。因此,在这两种情况下,另一列都会有空值(我知道空值的问题,但在考虑并研究了处理这个问题的最佳方法之后,我决定这样做,因为我只有少量属性)。我的问题出在 CHECK CONSTRAINT 中。我试过这样做:
CREATE TABLE manufactured (
PID INT NOT NULL,
PARTTYPE NUMBER (1) NOT NULL,
CHECK (PARTTYPE IN (1,2)),
CONSTRAINT REFMAN FOREIGN KEY (PID, PARTTYPE) REFERENCES PART (PID, PARTTYPE),
LOCATION VARCHAR (50),
CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL),
CONSTRAINT LOC2 CHECK(PARTTYPE=2 AND LOCATION IS NULL),
LEAD_TIME VARCHAR (50),
CONSTRAINT LEADTIME CHECK (PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
CONSTRAINT LEADTIME2 CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL),
CONSTRAINT PK_MAN PRIMARY KEY (PID));
这不起作用。
我尝试插入一条记录如下:
insert into manufactured(PID, PARTTYPE, LOCATION) values(101,1,'Warehouse1');
然后我收到错误:
ORA-02290: 违反检查约束 (*****.LEADTIME)
我也试过:
insert into manufactured values (101,1,'Warehouse1');
我得到错误:
ORA-00947: 值不足
最后是这个:
insert into manufactured(PID, PARTTYPE, LEAD_TIME) VALUES (102, 2, '2 WEEKS');
我收到以下错误:
ORA-02290: 违反检查约束 (****.LEADTIME2)
预先感谢您的帮助。
我不知道你用的是哪个RDBMS。例如在 Oracle CHECK 约束中接受空值。
据我所知,每种派对类型都有不同的 attributes/datatypes。有两种方法:
- 将数据分成两个单独的 table。在此解决方案中,可能需要一些触发器。
- tab1:manufactured_1(PID 1 的属性+约束)
- tab2:manufactured_2(PID 2 的属性+约束)
- 使用 "after insert/update" 触发器 - 它会将不必要的数据设置为空。例如,如果在 table 中 PID = 1 的时间比触发器会将时间值设置为空。
这条插入语句:
insert into manufactured(PID, PARTTYPE, LOCATION)
values(101,1,'Warehouse1');
...失败,因为您的 LEADTIME
约束要求 PARTTYPE=2
。 (这是一个 AND
条件,因此如果 PARTTYPE=1
无论 LEAD_TIME
的值如何,约束都会失败。)
这就是我认为您正在寻找的:
CREATE TABLE manufactured (
PID INT NOT NULL,
PARTTYPE NUMBER (1) NOT NULL,
CHECK (PARTTYPE IN (1,2)),
CONSTRAINT REFMAN FOREIGN KEY (PID, PARTTYPE) REFERENCES PART (PID, PARTTYPE),
LOCATION VARCHAR (50),
--CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL),
--CONSTRAINT LOC2 CHECK(PARTTYPE=2 AND LOCATION IS NULL),
CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL OR PARTTYPE=2 AND LOCATION IS NULL),
LEAD_TIME VARCHAR (50),
--CONSTRAINT LEADTIME CHECK (PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
--CONSTRAINT LEADTIME2 CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL),
CONSTRAINT LEADTIME CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL OR PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
CONSTRAINT PK_MAN PRIMARY KEY (PID));
基本上,对每一列进行一个约束,强制执行该列的整套逻辑。
如果您真的想要在每一列上设置两个约束,您也可以这样做。如果是这样,post 发表评论,我将更新此答案。否则我不想 clutter/confuse 这个问题。
- 的错误
ORA-00947: not enough values
insert into manufactured values (101,1,'Warehouse1');
很明显,
因为 table(manufactured
) 的最后一列 (lead_time
) 对于 values
列表缺失。
错误ORA-02290: check constraint
源于依赖
检查约束 LEADTIME
和 LEADTIME2
之间的条件,
这些应该合并为
CONSTRAINT LEADTIME CHECK ((PARTTYPE=2 AND LEAD_TIME IS NOT NULL) OR (PARTTYPE=1 AND LEAD_TIME IS NULL))
。
相同的逻辑也适用于约束 LOC
和 LOC2
,它们应该产生
CONSTRAINT LOC CHECK ((PARTTYPE=1 AND LOCATION IS NOT NULL) OR (PARTTYPE=2 AND LOCATION IS NULL))
我正在为 Uni 做一个项目,我对数据库没有太多的了解或经验。我正在尝试在 Oracle 中使用 table 创建一个数据库,其中包含可以是 2 种类型的制造零件,比如 1 和 2。当零件是类型 1 时,我将在 table 中存储它位置,当它是类型 2 时,我将在相同的 table 中存储提前期。因此,在这两种情况下,另一列都会有空值(我知道空值的问题,但在考虑并研究了处理这个问题的最佳方法之后,我决定这样做,因为我只有少量属性)。我的问题出在 CHECK CONSTRAINT 中。我试过这样做:
CREATE TABLE manufactured (
PID INT NOT NULL,
PARTTYPE NUMBER (1) NOT NULL,
CHECK (PARTTYPE IN (1,2)),
CONSTRAINT REFMAN FOREIGN KEY (PID, PARTTYPE) REFERENCES PART (PID, PARTTYPE),
LOCATION VARCHAR (50),
CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL),
CONSTRAINT LOC2 CHECK(PARTTYPE=2 AND LOCATION IS NULL),
LEAD_TIME VARCHAR (50),
CONSTRAINT LEADTIME CHECK (PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
CONSTRAINT LEADTIME2 CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL),
CONSTRAINT PK_MAN PRIMARY KEY (PID));
这不起作用。
我尝试插入一条记录如下:
insert into manufactured(PID, PARTTYPE, LOCATION) values(101,1,'Warehouse1');
然后我收到错误: ORA-02290: 违反检查约束 (*****.LEADTIME)
我也试过:
insert into manufactured values (101,1,'Warehouse1');
我得到错误:
ORA-00947: 值不足
最后是这个:
insert into manufactured(PID, PARTTYPE, LEAD_TIME) VALUES (102, 2, '2 WEEKS');
我收到以下错误: ORA-02290: 违反检查约束 (****.LEADTIME2)
预先感谢您的帮助。
我不知道你用的是哪个RDBMS。例如在 Oracle CHECK 约束中接受空值。
据我所知,每种派对类型都有不同的 attributes/datatypes。有两种方法:
- 将数据分成两个单独的 table。在此解决方案中,可能需要一些触发器。
- tab1:manufactured_1(PID 1 的属性+约束)
- tab2:manufactured_2(PID 2 的属性+约束)
- 使用 "after insert/update" 触发器 - 它会将不必要的数据设置为空。例如,如果在 table 中 PID = 1 的时间比触发器会将时间值设置为空。
这条插入语句:
insert into manufactured(PID, PARTTYPE, LOCATION) values(101,1,'Warehouse1');
...失败,因为您的 LEADTIME
约束要求 PARTTYPE=2
。 (这是一个 AND
条件,因此如果 PARTTYPE=1
无论 LEAD_TIME
的值如何,约束都会失败。)
这就是我认为您正在寻找的:
CREATE TABLE manufactured (
PID INT NOT NULL,
PARTTYPE NUMBER (1) NOT NULL,
CHECK (PARTTYPE IN (1,2)),
CONSTRAINT REFMAN FOREIGN KEY (PID, PARTTYPE) REFERENCES PART (PID, PARTTYPE),
LOCATION VARCHAR (50),
--CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL),
--CONSTRAINT LOC2 CHECK(PARTTYPE=2 AND LOCATION IS NULL),
CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL OR PARTTYPE=2 AND LOCATION IS NULL),
LEAD_TIME VARCHAR (50),
--CONSTRAINT LEADTIME CHECK (PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
--CONSTRAINT LEADTIME2 CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL),
CONSTRAINT LEADTIME CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL OR PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
CONSTRAINT PK_MAN PRIMARY KEY (PID));
基本上,对每一列进行一个约束,强制执行该列的整套逻辑。
如果您真的想要在每一列上设置两个约束,您也可以这样做。如果是这样,post 发表评论,我将更新此答案。否则我不想 clutter/confuse 这个问题。
- 的错误
ORA-00947: not enough values
insert into manufactured values (101,1,'Warehouse1');
很明显,因为 table(
manufactured
) 的最后一列 (lead_time
) 对于values
列表缺失。 错误
ORA-02290: check constraint
源于依赖 检查约束LEADTIME
和LEADTIME2
之间的条件, 这些应该合并为
CONSTRAINT LEADTIME CHECK ((PARTTYPE=2 AND LEAD_TIME IS NOT NULL) OR (PARTTYPE=1 AND LEAD_TIME IS NULL))
。相同的逻辑也适用于约束
LOC
和LOC2
,它们应该产生CONSTRAINT LOC CHECK ((PARTTYPE=1 AND LOCATION IS NOT NULL) OR (PARTTYPE=2 AND LOCATION IS NULL))