【发布时间】:2017-03-31 14:40:37
【问题描述】:
我是 Oracle SQL 的新手,今天我想尝试一个与“UNIQUE”语句相同的示例触发器。因此,触发器应在插入之前检查数据集中是否已存在特定属性(“cityid”)。
问题是我的触发器没有触发!编译工作正常,但没有一个命令工作。
这里是:
CREATE OR REPLACE TRIGGER check_cityid
BEFORE INSERT
ON city
FOR EACH ROW
BEGIN
IF :old.cityid <> :new.cityid THEN
insert into city (cityid, name, country, province, population, latitude, longitude) values (:new.cityid, :new.name, :new.country, :new.province, :new.population, :new.latitude, :new.longitude);
DBMS_OUTPUT.PUT_LINE('OK');
ELSE
DBMS_OUTPUT.PUT_LINE('The attribute CITYID is already present!');
END IF;
END;
/
这是我的表“城市”,主键为 NAME+COUNTRY+PROVINCE:
SQL> describe city;
Name Null? Typ
----------------------------------------------------- -------- -------
NAME NOT NULL VARCHAR2(35)
COUNTRY NOT NULL VARCHAR2(4)
PROVINCE NOT NULL VARCHAR2(32)
POPULATION NUMBER
LONGITUDE NUMBER
LATITUDE NUMBER
CITYID NUMBER(38)
顺便说一句,我知道 PK 应该指的是“cityid”,但这只是一个练习......
有人知道如何解决这个问题吗?
提前致谢。
【问题讨论】:
-
:old.city_id对于插入触发器总是为空; theoldpseudorecord is only populated for update and delete。我认为您误解了old所指的内容,它不是表中的每个现有行。 (但是,查询触发器内的表会得到一个变异表错误......)。这并不意味着它没有开火。插入时会看到什么?您有set serveroutput on或您的客户的等价物吗? -
另外,
before insert在插入之前触发,而不是而不是插入。因此,如果您的触发器有效,它将在:old.cityid <> :new.cityid时插入重复的行。好好阅读文档:docs.oracle.com/database/121/CNCPT/srvrside.htm#CNCPT88945 -
好的,首先谢谢。其次,我想我需要一个 INSTEAD-OF 触发器?我正在查询旧的 cityid 以进行比较:'select cityid into cityid_old from city where cityid=:new.cityid;'
-
@MichaelGierer -
:old.city_id确实 not 给你相当于那个查询。instead of触发器适用于视图,而不是表。如果您的before insert触发器发现一个问题,意味着插入应该不发生,您可以引发异常;否则它将正常完成。但是对现有行的测试将是一个问题——对于变异表错误和并发性。我知道你在做实验,但这不是通过触发器来完成的。