2014-03-07 64 views
1
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 [email protected] 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); 

當我嘗試將數據插入上述帳戶表時,觸發器觸發並始終回滾事務。我不明白爲什麼。任何人都可以請解釋 謝謝。插入觸發器時不考慮條件是否觸發

錯誤顯示如下:

消息3609,級別16,狀態1,2號線
在觸發器中結束交易。該批次已被中止。

+1

您需要重寫觸發器 - 假設它始終在「插入」中只有一行 - 這是** NOT * * 案子!如果您插入多行,則「插入」將包含**多於一行**,並且您的分配「SELECT @ bcode = bcode,@ cusNo = customer_no FROM inserted;'將任意選擇其中一行(並忽略其餘的部分)。您的觸發器**需要在'Inserted'中插入多行** –

+1

另外,由於您使用的是INSTEAD OF INSERT觸發器,因此您需要在觸發器中執行INSERT ** 。我不會在任何地方看到......在INSERT之後,您不應該調用「COMMIT」 - 這會自動發生。如果您想中止操作,請使用'ROLLBACK'。 –

+0

所以你試圖做的是創建一個表,其中任何特定的'bcode'和'customer_no'組合不能超過5行? –

回答

1

正如我在評論說 - 通常情況下,Inserted可以和將包含多行和當前觸發不能與處理。

但是,如果你知道並能保證你永遠只打算在一次插入一行 - 那麼你的觸發仍然有缺陷:由於您使用的INSTEAD OF INSERT

  • ,在情況一切都OK了,你必須實際INSERT - 這觸發運行,而不是通常的SQL插入....所以,如果一切順利,你需要做的插入操作

  • 也:唐別叫觸發器中的- 如果一切正常,它將自動處理。僅使用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在舍入錯誤和缺乏精確度方面非常糟糕......

+0

你的答案是很清楚的,感謝你 – Roledenez

+0

但有一個邏輯錯誤,這個觸發器允許插入5個以上的帳戶到同一個bcode和customer_no賬戶表 – Roledenez

+0

@SelaruSinbath:它允許** 6 **行 - 因爲你正在檢查'<= 5'(在發生'INSERT'之前)它如果已經有5行,並且允許插入第六行,**將成功**。你需要明白:當你檢查'<= 5'時,新的'INSERT'還沒有發生**呢!你以後會這樣做。所以,如果你想限制它最多5行,你需要檢查'@count <5'(不是'<=') –