我们想要创建一个触发器,检查新测量(= messung)点是否位于当前冰川形状(= umriss)内。
表格如下:
冰川形状(= Umriss)
create table umriss
(
umr_nr number (4) not null,
umr_datum date,
GLST_ID number (4) not null,
shape mdsys.sdo_geometry,
GLETSCHER_ID number (3) not null
)
;
alter table umriss
add constraint umriss_glst_pk
primary key (umr_nr, GLST_ID, GLETSCHER_ID)
;
ALTER TABLE umriss
ADD CONSTRAINT umriss_gletscherstand_fk
FOREIGN KEY (GLST_ID, GLETSCHER_ID)
REFERENCES GLETSCHERSTAND(GLST_ID, GLETSCHER_ID);
新衡量(= Messung)
CREATE TABLE MESSUNG
(
MESS_NR number (4) not null,
MESS_DAT date,
MESS_AKK number (20) NOT NULL,
MESS_SCHMELZ number (20) NOT NULL,
SHAPE mdsys.sdo_geometry,
MESS_BILD blob,
KMPGN_NR NUMBER (4) NOT NULL
);
ALTER TABLE MESSUNG
ADD CONSTRAINT messung_pk
PRIMARY KEY (MESS_NR);
ALTER TABLE MESSUNG
ADD CONSTRAINT messung_messkampagne_fk
FOREIGN KEY (KMPGN_NR)
REFERENCES MESSKAMPAGNE(KMPGN_NR);
触发
CREATE OR REPLACE
TRIGGER MESSUNG_in_UMRISS_TRI
BEFORE INSERT OR UPDATE ON MESSUNG
FOR EACH ROW
DECLARE
num_check NUMBER;
BEGIN
SELECT COUNT (*) INTO num_check
FROM UMRISS u
WHERE mdsys.sdo_contains (u.shape, :NEW.point) = 'TRUE';
IF num_check <> 1
THEN
RAISE_APPLICATION_ERROR (=20500, 'Messung in keinem Umriss')
END IF;
END;
我们如何补充功能,以便触发器只检查最大的冰川形状? 谢谢你的帮助!
答案 0 :(得分:0)
这将返回UMRISS的一行,该行与表中的最新日期相匹配。
SELECT COUNT (*) INTO num_check
FROM UMRISS u
WHERE mdsys.sdo_contains (u.shape, :NEW.point) = 'TRUE'
AND u.umr_datum = ( select max(d.;umr_datum) from UMRISS d );
这种查询是将历史数据保存在与当前记录相同的表格中的代价。
答案 1 :(得分:0)
似乎POINT未在您的示例中定义?
但是,您可能会考虑检查约束,因为只有在插入或更新MESSUNG记录时才会强制执行触发器,但在UMRISS更改时则不会强制执行
alter table MESSUNG add constraint MESSUNG_CC_CONTAINS check(mdsys.sdo_contains (shape, point) = 'TRUE')
如果您经常更新UMRISS记录,则执行此类约束可能根本不可行,因为Oracle必须在更新或删除UMRISS时检查所有MESSUNG记录。也许可以考虑MESSUNG和UMRISS之间的另一个映射表,您可以单独更新。