2011-12-04 170 views
3

感谢您的阅读。我目前正在为一家假设商店开发一个约10个实体的数据库。因此,主要实体是Customer_Order,此触发器的目的是在Customer_order中插入或更新一行时检查客户的邮政编码是否为空。如果它为空,则触发器应该发出警告。Oracle触发器如果语句条件没有得到满足?

CREATE OR REPLACE TRIGGER Check_Order 
BEFORE INSERT OR UPDATE ON Customer_Order 
for each row 
DECLARE ShipAddress customer.ship_address.post_code%TYPE; 
BEGIN 
IF (ShipAddress = '') then 
RAISE_APPLICATION_ERROR(-20103, 'Shipping Address is empty'); 
END IF; 
END; 
. 
run 

我知道有没有“其他”,但我没有任何其他操作以外,以更新其它表。 不要担心ShipAddress,我已经试过这个更简单的属性,它根本不会触发。所发生的只是该行将被插入或更新,所以它不符合条件。我尝试了各种方法,比如“if(Payment_No ='PAYM0001')”,它不起作用,是因为我使用的是每个而不是语句级触发器吗?

回答

6

Oracle默认将空字符串(即长度为零的字符串)转换为NULL。所以在你的专栏中永远不会有''值。因此,IF语句永远不会是真的。您需要在触发检查NULL:

IF (ShipAddress IS NULL) then 
    RAISE_APPLICATION_ERROR(-20103, 'Shipping Address is empty'); 
END IF; 

但你要真的,真的跟随本的意见和简单的声明,列NOT NULL,而不是使用触发器来检查。

编辑

你能做到不空支票与你的表检查约束:

CREATE TABLE FOO 
(
    shipping_address ship_addres, 
    CONSTRAINT check_post_code CHECK (shipping_address.post_code IS NOT NULL) 
) 
+0

啊我明白了。我实际上不知道如何创建一个名为addressType的类型来声明它不为null。在我的系统中,所有客户和员工(“人员”的子类型)都继承了包含其各种值的地址类型,并且我无法弄清楚如何在不制作对象表的情况下将其实际设置为NOT NULL。如果你知道一种方式,我会很感激,如果你可以花时间分享它。谢谢你的帮助! –

+0

@MoMoosa:看看我编辑的例子没有如何声明你的类型的属性不为null –

1

Oracle使用3值逻辑,null是第三个值,可能是真,假或不存在,null是不存在的,等于没有,你不能用等号运算符测试null,使用IF :new.ShipAddress is null来测试空值

你还错误地引用该列中的扳机。有没有必要宣布任何东西,你必须引用:new:old值。This是一个很好的资源。

通过在表上设置约束来禁止空值会更好,所以shipaddress永远不能为空。见here。所以,

alter table my_table modify shipaddress not null; 

把它添加到表中。尽管在创建表格时添加约束会更好。这样做也会稍微加快速度,因为您不需要评估触发器。

编辑:

shipaddress已经被完整的地址的戒指,也许逗号分隔的?我肯定会推荐将地址的每个部分分离出来,例如,address1address2, address3,town,county,postcode。我是英国人,所以根据需要改为statezip等。这使得查询和处理数据,如果你需要做的更多,更容易。

+0

谢谢你,我已经改变了表,工作得非常好。我应该解释一下shipAddress,它包含了包含城镇,县和邮政编码的地址类型,以及包含街道和号码的街道类型 - 在事后看来可能是不必要的 - 这是可行的。我完全同意,但我看过其他的学生只有单一字符串的地址,所以至少我得到这个部分是正确的。非常感谢您的帮助! –