CREATE TABLE Account(
account_no int,
balance real,
type_code int,
branch_no int,
Bcode int,
customer_no int,
CONSTRAINT account_pk PRIMARY KEY (account_no),
CONSTRAINT check_balance CHECK (balance>=0)
);
alter TRIGGER tr_check_accounts_in_accountTBL
ON account INSTEAD OF INSERT
AS
BEGIN
DECLARE @count int
DECLARE @bcode int
DECLARE @cusNo int
SELECT @bcode=bcode,@cusNo=customer_no
FROM inserted;
SELECT @count=COUNT(a.account_no)
FROM account a
WHERE a.bcode=@bcode AND a.customer_no = @cusNo
print @count;
IF(@count<=5)
commit transaction
ELSE
rollback transaction
END
INSERT INTO account(account_no,balance,type_code,bcode,branch_no,customer_no)
VALUES(1,60000,1,1,1,1);
当我尝试将数据插入到Account表上方时,触发器始终触发并回滚事务。我不明白为什么。任何人都可以请解释 谢谢。
错误显示如下:
Msg 3609,Level 16,State 1,Line 2
交易在触发器中结束。批次已中止。
答案 0 :(得分:1)
正如我在评论中所说 - 通常Inserted
可以并且将包含多行,而您当前的触发器无法处理。
但如果您知道并且可以保证您一次只能插入一行 - 那么您的触发器仍有缺陷:
,因为您使用的是INSTEAD OF INSERT
,如果一切正常,您必须执行INSERT
- 此触发器已运行而不是通常的SQL插入....所以如果一切顺利,你需要进行插入操作
另外:不要在触发器中调用COMMIT
- 如果一切正常,它将自动处理。如果情况不佳,仅使用ROLLBACK
中止INSERT
您需要使用以下内容:
CREATE TRIGGER tr_check_accounts_in_accountTBL
ON dbo.Account INSTEAD OF INSERT
AS
BEGIN
DECLARE @count int
DECLARE @bcode int
DECLARE @cusNo int
SELECT @bcode = bcode, @cusNo = customer_no
FROM inserted;
SELECT @count = COUNT(a.account_no)
FROM dbo.Account a
WHERE a.bcode = @bcode AND a.customer_no = @cusNo
IF(@count <= 5)
-- all is well, now DO the insert!
INSERT INTO dbo.Account (account_no, balance, type_code, branch_no, Bcode, customer_no)
SELECT
account_no, balance, type_code, branch_no, Bcode, customer_no
FROM
Inserted
ELSE
-- situation is not good -> abort the INSERT
ROLLBACK TRANSACTION
END
另外:我会强烈推荐不使用real
作为您的金钱价值 - 请改用DECIMAL(p, s)
! REAL
在舍入错误和缺乏准确性方面非常糟糕.....