如果Oracle中不存在另一个值,则将row的值设置为NULL

时间:2018-02-01 17:08:36

标签: sql oracle oracle11g

我正在使用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值可能很糟糕但只是希望它们在那里而不是空行

2 个答案:

答案 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。您可以同时使用触发器和约束来保证条件和转换。