建立触发器检查单据
主从表金额一致检查,先保存主表item_table,再保存从表items_table,保存items_table时根据id进行检查,sum(price)=price.
如果从数据库想办法控制,怎么建立触发器来控制呢?item_table:
id price
1 20items_table:
autoid id price
1 1 10
2 1 6
3 1 4create TRIGGER [dbo].pricecheck ON items_table
FOR INSERT
--FOR INSERT, UPDATE, DELETE
AS
begin
declare
@id int
set @id=(select id from inserted)
if (select round(price,2) from [item_table] where id=@id)
<> (select round(sum(isnull(price,0)),2) from [items_table] where id=@id)
RAISERROR ('金额不一致不允许保存,请检查!' , 16, 1)
end
这样建立触发器后发现,金额等于也无法保存,因为插入从表第一条记录时无法取到sum(price)
该怎样修改?
主从表金额一致检查,先保存主表item_table,再保存从表items_table,保存items_table时根据id进行检查,sum(price)=price.
如果从数据库想办法控制,怎么建立触发器来控制呢?item_table:
id price
1 20items_table:
autoid id price
1 1 10
2 1 6
3 1 4create TRIGGER [dbo].pricecheck ON items_table
FOR INSERT
--FOR INSERT, UPDATE, DELETE
AS
begin
declare
@id int
set @id=(select id from inserted)
if (select round(price,2) from [item_table] where id=@id)
<> (select round(sum(isnull(price,0)),2) from [items_table] where id=@id)
RAISERROR ('金额不一致不允许保存,请检查!' , 16, 1)
end
这样建立触发器后发现,金额等于也无法保存,因为插入从表第一条记录时无法取到sum(price)
该怎样修改?
create TRIGGER [dbo].pricecheck ON items_table
AFTER INSERT
--1.AFTER代替FOR
AS
begin
declare
@id int
set @id=(select id from inserted) if (select round(price,2) from [item_table] where id=@id)
<> (select round(sum(isnull(price,0)),2) from [items_table] where id=@id)
begin
-- 2.直接回滚 ,数据就不会保存了,
rollback
end
end
而是在所有可能增删改items_table表时,都做事务检查比较好。虽然会要写好多地方,但这是必须的。
因为比如你在插入时,要插入N条items_table记录,对整体再做检查,所以,这个事务是一个整体的。
@ID INT,
@Result SMALLINT OUTPUT -- -1表示金额不一致不允许保存,1表示成功
AS
BEGIN
SET NOCOUNT ON; SET XACT_ABORT ON
BEGIN TRANSACTION
DECLARE @A INT,
@B INT
SELECT @A=ROUND(price,2)
FROM [item_table] WITH(NOLOCK)
WHERE ID=@ID
SELECT @B=ROUND(SUM(ISNULL(price,0)),2)
FROM [items_table] WITH(NOLOCK)
WHERE ID=@ID
IF (@A<>@B)
BEGIN
SET @Result=-1
RETURN
END
ELSE
BEGIN
--执行保存代码
END
SET @Result=1
COMMIT TRANSACTION
END
GO
所以还得用触发器来做SQL的检查,没办法加存储过程到程序里调用。
请大家想想办法