插入和计算之前的数据库触发器

时间:2016-04-26 01:13:06

标签: mysql cursor ddl database-trigger

所以我有这些表:

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 个答案:

答案 0 :(得分:1)

我的天哪,从哪里开始?

对于初学者来说,行触发器永远不应该查询它所附着的表。 (MySQL将允许这样做;许多DBMS不会。)

INSERT行触发器始终可以访问通过 NEW 伪记录插入的行,该伪记录包含与基础表相同的列。 NEW 的内容是从VALUES语句的INSERT子句初始化的,以及您对 NEW进行的任何更改将反映在表格行中。

另一个问题是,chittyusers上的光标有一个无条件的SELECT,它将从表中获取每个行,而不仅仅是你想要的那一行。你实际上在做的是抓取userId几乎随机的值,这可能与你想要的值无关。你实际上甚至不需要使用光标;一个带有INSERT ... INTO子句的简单WHERE会更好用:

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;

我不打算为你编写整个触发器,但这些指针至少应该将错误消息降低到可管理的数量。