一个oracle触发器的优化请教(用友NC产品)
oracle数据库是用在我们公司用友NC财务软件上,NC版本是5.02。
我是公司的NC的系统管理员。
我们使用了资金管理系统,需要使用一个功能是填制结算凭证,如下图:
上图红色方框标示的是需要特别注意的,系统的要求必须“账户”和“客商辅助”必须一致,也就是这里的“账户”是北京公司,那么后面的“客商辅助”也必须选择北京公司,否则会出现账务和系统上的麻烦。
备注:我们公司对同一个分公司,账户和客商是同一个编码,比如北京公司,账户和客商编码都是010201,上海公司都是010301.
我经过查看后台数据库,在填制结算凭证的时候,影响到的是两个表,分包是结算分录fts_voucher_b,结算凭证fts_voucher,这两个表通过字段pk_voucher关联。
上图中的“账户”和“客商辅助”是存在fts_voucher_b中,但是不是直接的代码,比如010201,而是两个pk代码值。
经过几天的研究,我打算通过触发器完成这个账户和客商一致的问题,可是上面也说到,在填制结算凭证,后台存入fts_voucher_b中的是pk值,必须要凭证保存到数据库之后才能查询到不一致的情况。
查询结算分录账户和客商不一致的情况,我sql如下:
select bd_accid.accidcode, gl_freevalue.valuecode from fts_voucher_b, bd_accsubj, gl_freevalue, bd_accid where fts_voucher_b.pk_subject = bd_accsubj.pk_accsubj and fts_voucher_b.pk_ass = gl_freevalue.freevalueid and fts_voucher_b.dr = '0' and fts_voucher_b.pk_corp = '1162' and fts_voucher_b.pk_account = bd_accid.pk_accid and length(gl_freevalue.valuecode) = '6' and substr(gl_freevalue.valuecode, 0, 1) = '0' and bd_accid.accidcode != gl_freevalue.valuecode
create or replace trigger CHECK_VOUCHER before insert or update on fts_voucher for each rowdeclare -- local variables here pk_bas char(20); accode char(6); vcode char(6); cursor basjob(id char) is select fts_voucher_b.pk_voucher,bd_accid.accidcode, gl_freevalue.valuecode from fts_voucher_b,bd_accid, gl_freevalue where fts_voucher_b.pk_voucher = id and fts_voucher_b.pk_ass = gl_freevalue.freevalueid and fts_voucher_b.pk_account = bd_accid.pk_accid and length(gl_freevalue.valuecode) = '6' and substr(gl_freevalue.valuecode, 0, 1) = '0'; begin open basjob(:new.pk_voucher); loop fetch basjob into pk_bas, accode , vcode; exit when basjob%notfound; --raise_application_error(-20001,pk_accidcode||'hhh'); end loop; close basjob; if pk_bas is not null then if accode<>vcode then begin raise_application_error(-20001,'结算凭证号'||:new.cent_typeid||'账户和客商不一致,请修改!'); end; end if; end if;end CHECK_VOUCHER;