一、任务
11\采购单上的总金额,应该根据采购单明细数据自动更新,即在每次新增、修改、删除采购单明细数据后进行更新。
12\对于采购单而言,如果是已经审核的单据,就不能再删除
13\对于采购单,建立如下的视图(采购单编号,供应商编号,供应商名称,联系人,联系电话,采购日期),即采购单中包含了供应商的基本信息,现在想通过视图来添加新的采购单,且如果输入的供应商不存在就当做新的供应商添加到供应商表中。
二、PL/SQL
11\create or replace trigger tr_prefreshamount
after insert or update of piprice,pinum or delete on t_procure_items
for each row
begin
if inserting then
update t_main_procure
set pamount=nvl(pamount,0)+:new.pinum*:new.piprice
where pmid=:new.pmid;
elsif updating then
update t_main_procure
set pamount=nvl(pamount,0)-:old.pinum*:old.piprice+:new.pinum*:new.piprice
where pmid=:new.pmid;
elsif deleting then
update t_main_rocure
set pamount=nvl(pamount,0)-:old.pinum*:old.piprice
where pmid=:old.pmid;
end if;
end;
12\create or replace trigger tr_deletemainprocure
before delete on t_main_procure
for each row
begin
if :old.pstate='2' then
raise_application_error(-20014,:old.pmid||'单据已经审核,不能删除');
end if;
end;
13\create or replace view v_main_procure(采购单编号,供应商编号,供应商名称,联系人,联系电话,采购日期) as select
pmid,a.sid,sname,scontact,sphone,pdate
from t_main_procure a,t_supplier b
where a.sid=b.sid;
create or replace trigger tr_v_main_procure
instead of insert on v_main_procure
for each row
declare
v_p number:=0;
begin
insert into t_main_procure(pmid,sid) values(:new.采购单编号,:new.供应商编号);
select count(sid) into v_p from t_supplier where sid=:new.供应商编号;
if v_p=0 then
insert into t_supplier values(:new.供应商编号,:new.供应商名称,:new.联系人,:new.联系电话,null);
end if;
end;
三、相关
1\触发器是编译好的、存储在数据库中的特殊过程,其特殊之处在于:过程在需要的时候使用语句调用才能完成相应的功能,而触发器是满足条件以后自动触发执行的。使用触发器可以轻松实现数据库中跨越相关表的级联添加修改和删除,实现比CHECK约束更复杂的数据完整性,实现自定义的错误信息等功能。
2\创建触发器的基本语法是
CREATE [OR REPLACE] TRIGGER [模式.]触发器名
{BEFORE | AFTER | INSTEAD OF}
{DML事件 | DDL事件 | DATABASE事件}
ON {[模式.]表 | [模式.]视图 | DATABASE}
[FOR EACH ROW [WHEN 触发条件]]
[DECLARE
--声明变量;]
BEGIN
--触发器执行代码;
[EXCEPTION
--异常处理代码;]
END;
3\在Oracle触发器中,有两个特殊的伪记录——:NEW和:OLD,之所以叫伪记录,是因为它们不是真实的记录,但是使用起来,它们就像在过程中使用的记录变量一样方便,它们被当做trigger_table%rowtype来处理,不过不需要定义。在触发器中,满足了insert\update\delete操作条件以后就可以根据情况使用“:NEW”和“:OLD”记录类型来引用所添加的记录值(:NEW),修改之前的记录值(:OLD)和修改以后的记录值(:NEW),以及删除的那条记录值(:OLD)。
11\采购单上的总金额,应该根据采购单明细数据自动更新,即在每次新增、修改、删除采购单明细数据后进行更新。
12\对于采购单而言,如果是已经审核的单据,就不能再删除
13\对于采购单,建立如下的视图(采购单编号,供应商编号,供应商名称,联系人,联系电话,采购日期),即采购单中包含了供应商的基本信息,现在想通过视图来添加新的采购单,且如果输入的供应商不存在就当做新的供应商添加到供应商表中。
二、PL/SQL
11\create or replace trigger tr_prefreshamount
after insert or update of piprice,pinum or delete on t_procure_items
for each row
begin
if inserting then
update t_main_procure
set pamount=nvl(pamount,0)+:new.pinum*:new.piprice
where pmid=:new.pmid;
elsif updating then
update t_main_procure
set pamount=nvl(pamount,0)-:old.pinum*:old.piprice+:new.pinum*:new.piprice
where pmid=:new.pmid;
elsif deleting then
update t_main_rocure
set pamount=nvl(pamount,0)-:old.pinum*:old.piprice
where pmid=:old.pmid;
end if;
end;
12\create or replace trigger tr_deletemainprocure
before delete on t_main_procure
for each row
begin
if :old.pstate='2' then
raise_application_error(-20014,:old.pmid||'单据已经审核,不能删除');
end if;
end;
13\create or replace view v_main_procure(采购单编号,供应商编号,供应商名称,联系人,联系电话,采购日期) as select
pmid,a.sid,sname,scontact,sphone,pdate
from t_main_procure a,t_supplier b
where a.sid=b.sid;
create or replace trigger tr_v_main_procure
instead of insert on v_main_procure
for each row
declare
v_p number:=0;
begin
insert into t_main_procure(pmid,sid) values(:new.采购单编号,:new.供应商编号);
select count(sid) into v_p from t_supplier where sid=:new.供应商编号;
if v_p=0 then
insert into t_supplier values(:new.供应商编号,:new.供应商名称,:new.联系人,:new.联系电话,null);
end if;
end;
三、相关
1\触发器是编译好的、存储在数据库中的特殊过程,其特殊之处在于:过程在需要的时候使用语句调用才能完成相应的功能,而触发器是满足条件以后自动触发执行的。使用触发器可以轻松实现数据库中跨越相关表的级联添加修改和删除,实现比CHECK约束更复杂的数据完整性,实现自定义的错误信息等功能。
2\创建触发器的基本语法是
CREATE [OR REPLACE] TRIGGER [模式.]触发器名
{BEFORE | AFTER | INSTEAD OF}
{DML事件 | DDL事件 | DATABASE事件}
ON {[模式.]表 | [模式.]视图 | DATABASE}
[FOR EACH ROW [WHEN 触发条件]]
[DECLARE
--声明变量;]
BEGIN
--触发器执行代码;
[EXCEPTION
--异常处理代码;]
END;
3\在Oracle触发器中,有两个特殊的伪记录——:NEW和:OLD,之所以叫伪记录,是因为它们不是真实的记录,但是使用起来,它们就像在过程中使用的记录变量一样方便,它们被当做trigger_table%rowtype来处理,不过不需要定义。在触发器中,满足了insert\update\delete操作条件以后就可以根据情况使用“:NEW”和“:OLD”记录类型来引用所添加的记录值(:NEW),修改之前的记录值(:OLD)和修改以后的记录值(:NEW),以及删除的那条记录值(:OLD)。
4\?在before行级触发器中,可以给:NEW引用列进行赋值,而且在触发器中,可以使用when来进行触发器触发的条件的设置,方便在系统开发中使用触发器。所谓before触发器是指在语句执行之前先执行触发器,再执行本语句,如果是after触发器就是先执行语句,再触发执行触发器。