2016-04-26 3 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; 

Что Im пытается сделать, это проверить, если дата операции такая же, как очищенную дату в 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 позволит этому, многий DBMSes не будет.)

Триггер INSERT строки всегда имеет доступ к строке вставляется через NEW pseudorecord, который содержит те же столбцы, как базовую таблицу. Содержание NEW инициализируется из пункта в INSERT заявлении VALUES, и любые изменения, внесенные в NEW будут отражены в строке таблицы после того, как вставка завершается.

Другая проблема заключается в том, что курсор на chittyusers имеет безусловный SELECT, которая будет захватывать каждый строку из таблицы, а не только тот, который вы хотите. То, что вы на самом деле делаете, - это захват почти случайного значения для userId, который, вероятно, не имеет ничего общего с тем, который вы хотите. На самом деле вам даже не нужно использовать курсор для этого; простой INSERT ... INTO с WHERE пункт будет работать лучше:

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

В-третьих, ваша структура СЛУЧАЙ является излишним; Вы можете сделать то же самое с простым IF:

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

Я не о том, чтобы написать весь триггер для вас, но эти указатели должны, по крайней мере, получить сообщения об ошибках вплоть до управляемого количества.

+0

спасибо. Выяснил это благодаря вам. но почему существует проблема с использованием случая? – luffy

+0

Нет проблем; это просто не нужно. С его помощью сокращаются переменные, строки кода и сложность. –

+0

Я использую это неправильно, хотя ?. если да, как бы я его изменил? – luffy

Смежные вопросы