日期:2014-05-19  浏览次数:20433 次

咨询一个触发器的写法
公司对于原材料、半成品、成品的实绩输入都存于XSACT表,原材料允许分批进行实绩输入。
原材料的项目编码起始于 'Z ',成品、半成品的项目编码不起始于 'Z '。
原材料的订单记录在XSLIP表里面,主键是PORDER(订号)和EDA(支号)
XSLIP_MATERIAL_ENDFLAG表通过PORDER和EDA与XSLIP表关联,里有个ENDFLAG字段用来记录某个原材料订单是否应该结束,规则是:
如果某个原材料订单的“合格入库数量合计”/“订单的计划数量”> 1.05,ENDFLAG应=2
如果某个原材料订单的“合格入库数量合计”/“订单的计划数量”属于[0.95,1.05]ENDFLAG应=1
如果某个原材料订单的“合格入库数量合计”/“订单的计划数量” <0.95,ENDFLAG应=0

我现在要在XSACT表上面建立一个触发器,对所有原材料的实绩输入操作(包括新增、修改、删除),检查它的“合格入库数量合计”(这个我自定义了一个函数可以计算出一个值),并与“订单的计划数量”(在XSLIP表里的KVOL字段)作比较,然后自动更改XSLIP_MATERIAL_ENDFLAG表里的ENDFLAG字段,怎么做呢?

写触发器时的疑问:
(1)我要对于DELETE   INSERT   UPDATE   分开写触发器还是写成一个?
(2)XSACT表可能有半成品和成品的实绩输入,对于这些不要调用触发器
(3)如果某人一次进行了多条原材料的实绩输入,触发器是一条一条运行的吗?

很多疑问使我无法继续写触发器,还请大侠帮忙一下,万分感激!

--附我写的DELETE触发器:
CREATE   TRIGGER   [dbo].[trgAutoSetMaterialEndFlag_DELETE]   ON   [dbo].[XSACT]  
FOR   DELETE
AS  
BEGIN
DECLARE   @DELETED_PORDER   VARCHAR(18)
DECLARE   @DELETED_EDA   INT
DECLARE   @POKVOL   DECIMAL(28,2)
DECLARE   @SUMKINPUT   DECIMAL(28,2)

SELECT   @DELETED_PORDER=LEFT(PORDER,8),@DELETED_EDA=EDA   FROM   DELETED   WHERE   LEFT(PORDER,2)= 'XX '   --起始于XX的是原材料的实绩输入
SELECT   @POKVOL=KVOL   FROM   XSLIP   WHERE   PORDER=@DELETED_PORDER   AND   EDA=@DELETED_EDA
SELECT   @SUMKINPUT=dbo.GetSumSactInput_K2(@DELETED_PORDER,@DELETED_EDA)   --dbo.GetSumSactInput_K2是用来计算“合格入库数量合计”的
IF   @SUMKINPUT/@POKVOL   > 1.05
UPDATE   XSLIP_MATERIAL_ENDFLAG   SET   ENDFLAG= '2 'WHERE   PORDER=@DELETED_PORDER   AND   EDA=@DELETED_EDA
ELSE   IF   @SUMKINPUT/@POKVOL   <=1.05   AND   @SUMKINPUT/@POKVOL   > =0.95
UPDATE   XSLIP_MATERIAL_ENDFLAG   SET   ENDFLAG= '1 'WHERE   PORDER=@DELETED_PORDER   AND   EDA=@DELETED_EDA
ELSE
UPDATE   XSLIP_MATERIAL_ENDFLAG   SET   ENDFLAG= '0 'WHERE   PORDER=@DELETED_PORDER   AND   EDA=@DELETED_EDA
END

------解决方案--------------------
(1)我要对于DELETE INSERT UPDATE 分开写触发器还是写成一个?
一起写for delete,insert,update ;
(2)XSACT表可能有半成品和成品的实绩输入,对于这些不要调用触发器
也用触发器!
(3)如果某人一次进行了多条原材料的实绩输入,触发器是一条一条运行的吗?
一条一条的运行!
------解决方案--------------------
CREATE TRIGGER [dbo].[trgAutoSetMaterialEndFlag_DELETE] ON [dbo].[XSACT]
INSTEAD OF DELETE
AS
BEGIN

UPDATE A SET ENDFLAG= CASE WHEN SUMKINPUT> 1.05 THEN '2 ' WHEN SUMKINPUT <=1.05 THEN '1 ' ELSE '0 ' END
FROM XSLIP_MATERIAL_ENDFLAG AS A,
(SELECT Y.PORDER,X.EDA,Y.KVOL,
dbo.GetSumSactInput_K2(Y.PORDER,X.EDA)/Y.KVOL AS SUMKINPUT --dbo.GetSumSactInput_K2是用来计算“合格入库数量合计”的
FROM DELETED X
JOIN XSLIP Y ON Y.PORDER=LEFT(X.PORDER,8) AND Y.EDA=X.EDA
WHERE LEFT(X.PORDER,2)= 'XX ' --起始于XX的是原材料的实绩输入
)AS B
WHERE A.PORDER=B.PORDER AND A.EDA=B.EDA


DELETE FROM XSACT WHERE --+条件......... 然后再手动删除相关记录


END
--INSERT,UPDATE 同理


(1)我要对于DELETE INSERT UPDATE 分开写触发器还是写成一个?
DELETE,INSERT,UPDATE 触发器分开做
(2)XSACT表可能有半成品和成品的实绩输入,对于这些不要调用触发器
根据LEFT(X.PORDER,2)= 'XX '等等条件
(3)如果某人一次进行了多条原材料的实绩输入,触发器是一条一条运行的吗?
不要使用变量,3表关联操作(看上面的写法),用 INSTEAD OF 写法,手动操作。确保多条记录同步更新