我正在使用Oracle数据库并尝试添加一个约束,如果有一个chemical_outlier,则将chemical_value设置为NULL。我一直在搜索Oracle文档以寻找可能的解决方案,但卡住了
Create table chemical
(
chemical_id char(3) not null,
chemical_name varchar2(50) not null,
chemical_value numeric,
checmical_outlier varchar(50),
constraint checkChemical <DONT KNOW HOW TO APPROACH THIS>
)
只需要某种方向即将到来。我知道NULL值可能很糟糕但只是希望它们在那里而不是空行
答案 0 :(得分:1)
检查约束不会将任何内容设置为null,但会阻止输入无效值:
create table chemical
( chemical_id varchar2(3) not null
, chemical_name varchar2(50) not null
, chemical_value numeric
, chemical_outlier varchar(50)
, constraint chem_value_or_outlier_chk
check (not (chemical_value is not null and chemical_outlier is not null)
and (chemical_value is not null or chemical_outlier is not null))
);
现在这些失败了:
insert into chemical (chemical_id, chemical_name, chemical_value, chemical_outlier)
values ('x', 'xyz', 123, 'outlier');
ORA-02290: check constraint (XXX.CHEM_VALUE_OR_OUTLIER_CHK) violated
insert into chemical (chemical_id, chemical_name, chemical_value, chemical_outlier)
values ('x', 'xyz', null, null);
ORA-02290: check constraint (XXX.CHEM_VALUE_OR_OUTLIER_CHK) violated
但这些成功了:
insert into chemical (chemical_id, chemical_name, chemical_value, chemical_outlier)
values ('x', 'xyz', null, 'outlier');
insert into chemical (chemical_id, chemical_name, chemical_value, chemical_outlier)
values ('x', 'xyz', 123, null);
答案 1 :(得分:0)
如果在没有列的情况下调用INSERT,则默认情况下该列设置为NULL。因此,如果你可以控制INSERT,只需用3列调用它们,2列为强制列,1列为其他列。在这种情况下,您需要检查以确保任何人都会使用4列调用INSERT:
CONSTRAINT "CONSTRAINT_NAME"
CHECK ((chemical_value IS NULL AND checmical_outlier IS NOT NULL)
OR (chemical_value IS NOT NULL AND checmical_outlier IS NULL)) ENABLE
因此,如果有人尝试定义两列,则约束不接受INSERT。
但是,如果您有一个生成INSERT查询的表单或其他内容,即使您没有填充列,也会使用该值生成INSERT,其值为&#34;&#34; (空字符串),您需要一个触发器将其转换为NULL值,如:
CREATE OR REPLACE TRIGGER "TRIGGER_NAME"
BEFORE INSERT OR UPDATE ON chemical
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
IF :new.chemical_value = ''
THEN :new.chemical_value := NULL;
END IF;
IF :new.checmical_outlier = ''
THEN :new.checmical_outlier := NULL;
END IF;
END;
请注意,此触发器不会检查条件&#34;一个是填充而另一个是不是&#34;,触发器只是将空字符串转换为NULL。您可以同时使用触发器和约束来保证条件和转换。