问题:需要对表A进行以下操作的触发器:每次在表A的TRT_PROCEDURE列的值中插入INSERT时,将1添加到表B的“ TRT_INS_COUNT”列。如果TRT_PROCEDURE值在表B中不存在表B,在表B中添加一行,以将TRT_INS_COUNT设置为1。
每次在表A上执行DELETE时,如果该过程值在表B中存在,则在该表B的TRT_DEL_COUNT列中添加1。如果在表B中不存在该过程值,则在该表B的行B中添加一行程序并将TRT_DEL_COUNT设置为1。
每次对表A中的列TRT_PROCEDURE进行UPDATE时,将1添加到表B中的列TRT_UPD_COUNT中。如果它不在表B中,则在表B中添加一行以获取过程值,并将TRT_UPD_COUNT设置为1。表A中的TRT_PROCEDURE列值已更改,将TRT_UPD_COUNT加1作为旧过程值。
通过执行几个INSERT,DELETE和UPDATE进行测试,然后显示表B。
更新:每当将trt_procedure的值插入表B中时,第二个相同的trt_procedure(例如'88 -20')就不能正确地计入其指定的计数字段中。不知道哪里出了问题。
TABLE A
Name Null Type
TRT_ID NOT NULL NUMBER(3)
PAT_NBR NUMBER(4)
PHYS_ID NUMBER(3)
TRT_PROCEDURE VARCHAR2(5)
TRT_DATE DATE
TABLE B
Name Null Type
TRT_PROCEDURE NOT NULL VARCHAR2(5)
TRT_INS_COUNT NUMBER(3)
TRT_DEL_COUNT NUMBER(3)
TRT_UPD_COUNT NUMBER(3)
TEST SAMPLES
INSERT INTO A VALUES (11, 8031,101,'88-20',sysdate );
INSERT INTO A VALUES (12, 5872,101,'60-00',sysdate );
UPDATE A SET trt_procedure = '88-20' WHERE trt_id=6;
/*row trt_id =6 cloumn trt_procedure old value '54-60'
new value '88-20', which means Table B row '88-20' and
row '54-60 both trt_upd_count should add 1*/
DELETE FROM A WHERE trt_id=1;
/*row trt_id =1 cloumn trt_procedure value also '88-20', which means
that Table B row '88-20' trt_del_count should also add 1*/
CREATE OR REPLACE TRIGGER trt_stats_trg
BEFORE INSERT OR UPDATE OR DELETE OF TRT_procedure ON A FOR EACH ROW
BEGIN
IF INSERTING THEN
UPDATE B SET trt_ins_count = trt_ins_count+1
WHERE B.trt_procedure = :new.trt_procedure;
IF SQL%NOTFOUND THEN
INSERT INTO B (trt_procedure, trt_ins_count)
VALUES (:new.trt_procedure, 1);
END IF;
ELSIF UPDATING THEN
UPDATE B SET trt_upd_count = trt_upd_count+1
WHERE B.trt_procedure = :old.trt_procedure;
IF SQL%NOTFOUND THEN
INSERT INTO B (trt_procedure, trt_upd_count)
VALUES (:old.trt_procedure, 1);
END IF;
UPDATE B SET trt_upd_count = trt_upd_count+1
WHERE B.trt_procedure = :new.trt_procedure;
IF SQL%NOTFOUND THEN
INSERT INTO B (trt_procedure, trt_upd_count)
VALUES (:new.trt_procedure, 1);
END IF;
ELSIF DELETING THEN
UPDATE B SET trt_del_count = trt_del_count+1
WHERE B.trt_procedure = :old.trt_procedure;
IF SQL%NOTFOUND THEN
INSERT INTO B (trt_procedure, trt_del_count)
VALUES (:old.trt_procedure, 1);
END IF;
END IF;
END trt_stats_trg;
解决了一些问题。
表格:
create table a(
TRT_ID NUMBER(3) NOT NULL ,
PAT_NBR NUMBER(4),
PHYS_ID NUMBER(3),
TRT_PROCEDURE VARCHAR2(5),
TRT_DATE DATE
);
create table b(
TRT_PROCEDURE VARCHAR2(5) NOT NULL,
TRT_INS_COUNT NUMBER(3),
TRT_DEL_COUNT NUMBER(3),
TRT_UPD_COUNT NUMBER(3)
);
和触发
CREATE OR REPLACE TRIGGER trt_stats_trg
BEFORE INSERT OR UPDATE OR DELETE ON A FOR EACH ROW
BEGIN
IF INSERTING THEN
UPDATE B SET trt_ins_count = nvl(trt_ins_count,0)+1
WHERE B.trt_procedure = :new.trt_procedure;
IF SQL%NOTFOUND THEN
INSERT INTO B (trt_procedure, trt_ins_count)
VALUES (:new.trt_procedure, 1);
END IF;
ELSIF UPDATING('TRT_PROCEDURE') THEN
if nvl(:old.trt_procedure, 'X') <> nvl(:new.trt_procedure, 'X') then
UPDATE B SET trt_upd_count = nvl(trt_upd_count,0)+1
WHERE B.trt_procedure = :old.trt_procedure;
IF SQL%NOTFOUND THEN
INSERT INTO B (trt_procedure, trt_upd_count)
VALUES (:old.trt_procedure, 1);
END IF;
UPDATE B SET trt_upd_count = nvl(trt_upd_count,0)+1
WHERE B.trt_procedure = :new.trt_procedure;
IF SQL%NOTFOUND THEN
INSERT INTO B (trt_procedure, trt_upd_count)
VALUES (:new.trt_procedure, 1);
END IF;
end if;
ELSIF DELETING THEN
UPDATE B SET trt_del_count = nvl(trt_del_count, 0)+1
WHERE B.trt_procedure = :old.trt_procedure;
IF SQL%NOTFOUND THEN
INSERT INTO B (trt_procedure, trt_del_count)
VALUES (:old.trt_procedure, 1);
END IF;
END IF;
END trt_stats_trg;
/
关键点:
您可以UPDATING('COLUMN_NAME')
用来检测SQL何时影响特定列。
当为时UPDATING
,您可能希望检查未更改的更新,其中将值“ ABC”的列更新为“ ABC”。这通常发生在仅将所有列都包含在更新中的框架中,即使它们并没有真正改变。使用类似的东西来检测到这一点if nvl(:old.trt_procedure, 'X') <> nvl(:new.trt_procedure, 'X') then
。
TableB
没有计数的默认值,因此当原始触发器尝试更新table时B
,它成功...更新NULL
为NULL
,因为将1加到就会发生这种情况NULL
。这可以通过为0
表中的列分配默认值或使用NVL(trt_upd_count,0) + 1
代替来解决trt_upd_count + 1
。
:new
和的用法:old
。在此触发条件下,它们似乎是正确的,但这取决于您的业务案例。本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句