2016-04-26 148 views
0

所以我有這些表:數據庫觸發器和計算

CREATE TABLE `chittytransactions` (
    `ChittyTransactionID` int(11) NOT NULL, 
    `AuctionID` int(11) NOT NULL, 
    `ChittyAccNo` int(11) DEFAULT NULL, 
    `Date` datetime DEFAULT NULL, 
    `Amount` double DEFAULT NULL, 
    `Description` varchar(50) DEFAULT NULL, 
    `TransRefence` varchar(50) DEFAULT NULL COMMENT 'Reference from actual Bank transaction', 
    `TransStatus` tinyint(1) DEFAULT NULL COMMENT 'If Transaction Pending or Cleared', 
    `ClearanceDate` datetime DEFAULT NULL, 
    `PaymentMethod` int(1) DEFAULT NULL COMMENT '0- Cash, 1- bank transfer, 2- personal credit etc' 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

CREATE TABLE `chittyusers` (
    `ChittyAccNo` int(11) NOT NULL, 
    `UserId` int(11) NOT NULL, 
    `ChittyID` int(11) NOT NULL, 
    `LatePaymentFee` int(11) DEFAULT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

CREATE TABLE `users` (
    `UserId` int(11) NOT NULL, 
    `UserName` varchar(45) NOT NULL, 
    `UserNameVerified` tinyint(1) DEFAULT '0', 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

什麼即時試圖做的是檢查,如果交易日期是一樣的,在chittytransaction表中清除日期,如果不加一晚支付費用爲chittyusers表(最好根據日期計算,根據日期計算延遲支付的額外費用)。這應該在插入之前完成,我正在使用觸發器。到目前爲止,我有這樣的:

ROP TRIGGER IF EXISTS chitty_beforet_trig; 

DELIMITER ;; 
CREATE TRIGGER chitty_beforet_trig BEFORE Insert ON chittytransaction 
FOR EACH ROW 
    BEGIN 
    DECLARE `mainDate` datetime; 
    DECLARE `claredDate` datetime; 
    DECLARE `chitAccNo` INT(11); 
    DECLARE `userId` INT(11); 
    DECLARE `latePay` DOUBLE; 
    DECLARE late TINYINT; 
    DECLARE cursor1 CURSOR FOR SELECT ChittyAccNo FROM accounting.`chittyusers`; 
    DECLARE cursor2 CURSOR FOR SELECT `Date` FROM accounting.`chittyTransaction`; 
    DECLARE cursor3 CURSOR FOR SELECT ClearanceDate FROM accounting.`chittyTransaction`; 
    DECLARE cursor4 CURSOR FOR SELECT UserId FROM accounting.`users`; 

    OPEN cursor1; 
    OPEN cursor2; 
    OPEN cursor3; 
    OPEN cursor4; 

    FETCH cursor1 INTO chitAccNo; 
    FETCH cursor2 INTO mainDate 
    FETCH cursor3 INTO claredDate; 
    FETCH cursor3 INTO userId; 
    CASE 
     WHEN claredDated <> mainDate THEN 
      SET late ='1'; 
     ELSE 
      SET late = '0'; 
     END; 
    END CASE; 

    IF late THEN 
     UPDATE `chittyusers` SET LatePaymentFee = 50 WHERE UserId = userId; 
    END IF; 
CLOSE cursor1; 
CLOSE cursor2; 
CLOSE cursor3; 
CLOSE cursor4; 

END;; 
DELIMITER; 

我不斷收到許多不同的錯誤等的廣告,我不知道如果我這樣做是正確與否。以前從未使用過,所以它有點困難。任何人都可以告訴我,我做錯了請和任何解決方案,將不勝感激。

回答

1

我的天啊,從哪裏開始?

對於初學者,行觸發器不應該查詢它所附的表。 (MySQL將允許此;許多的DBMS不會。)

一種INSERT行觸發器始終有權訪問該行經由NEW pseudorecord,其含有相同的列底層表被插入。的NEW內容從INSERT語句的VALUES條款初始化,您對NEW任何變化,一旦插入完成後將會反映在表中一行。

另一個問題是,你對chittyusers光標具有無條件SELECT,這會搶從表中的每一行,不只是一個你想要的。你實際上在做的是抓取幾乎隨機的值爲userId,這可能與你想要的無關。你甚至不需要爲此使用光標;一個簡單的INSERT ... INTOWHERE子句將更好地工作:

SELECT `UserId` 
    INTO `userId` 
    FROM chittyusers 
    WHERE ChittyAccNo = NEW.ChittyAccNo; 

三,你的CASE結構是多餘的;你可以做同樣的用一個簡單的IF:

IF NEW.ClearanceDate <> NEW.`Date` THEN 
    UPDATE `chittyusers` 
    SET LatePaymentFee = 50 
    WHERE UserId = userId; 
END IF; 

我不會寫整個觸發你,但這些指針應該至少得到錯誤信息到可管理的數量。

+0

謝謝。多虧了你。但爲什麼使用案例會出現問題? – luffy

+0

沒有問題;它只是沒有必要。報廢它會減少變量,代碼行和複雜性。 –

+0

我使用它錯了嗎?如果是的話,我會如何改變它? – luffy