2016-04-26 80 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