触发器无法正常工作

时间:2013-10-24 22:50:50

标签: mysql triggers

我有一个触发器,更新客户部分在更新时正常工作。 我希望有人帮我纠正剩下的并告诉我这个代码的格式是什么,以便正确地使用更新/插入/删除触发器。

基本上我需要做的是审核插入/更新/删除的发票和付款。 审计行中的条目必须更新发票表金额和客户余额。 付款必须更新,以便调整到期余额。

此刻我到处都感到困惑 - 可能是因为这段时间我没有睡过大约18个多小时:(

以下是一切:

USE customercontrol;

CREATE TABLE customers (
  Id int(11) NOT NULL AUTO_INCREMENT,
  Name varchar(50) DEFAULT NULL,
  Address varchar(255) NOT NULL,
  DateCreated timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  Username varchar(255) NOT NULL,
  Password varchar(255) NOT NULL,
  Balance decimal(8, 2) NOT NULL DEFAULT 0.00,
  PRIMARY KEY (Id),
  INDEX Id (Id),
  UNIQUE INDEX Id_2 (Id)
)
ENGINE = INNODB
AUTO_INCREMENT = 12
AVG_ROW_LENGTH = 8192
CHARACTER SET latin1
COLLATE latin1_swedish_ci;

CREATE TABLE invoicelines (
  Id int(11) NOT NULL AUTO_INCREMENT,
  InvoiceId int(11) NOT NULL,
  Description varchar(255) DEFAULT NULL,
  DateCreated timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  Amount decimal(8, 2) NOT NULL DEFAULT 0.00,
  PRIMARY KEY (Id, InvoiceId),
  INDEX FK_invoicelines_invoices_Id (InvoiceId)
)
ENGINE = INNODB
AUTO_INCREMENT = 78
AVG_ROW_LENGTH = 5461
CHARACTER SET latin1
COLLATE latin1_swedish_ci;

CREATE TABLE invoicelines_audit (
  Id int(11) NOT NULL AUTO_INCREMENT,
  InvoiceId int(11) NOT NULL,
  Description varchar(255) DEFAULT NULL,
  DateCreated timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  Amount decimal(8, 2) NOT NULL DEFAULT 0.00,
  PRIMARY KEY (Id, InvoiceId)
)
ENGINE = INNODB
AUTO_INCREMENT = 452
AVG_ROW_LENGTH = 3276
CHARACTER SET latin1
COLLATE latin1_swedish_ci;

CREATE TABLE invoices (
  Id int(11) NOT NULL AUTO_INCREMENT,
  CustomerId int(11) NOT NULL,
  Description varchar(255) DEFAULT NULL,
  Amount decimal(8, 2) NOT NULL DEFAULT 0.00,
  DateCreated timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (Id),
  INDEX FK_invoices_customers_Id (CustomerId),
  UNIQUE INDEX UK_invoices_Id (Id)
)
ENGINE = INNODB
AUTO_INCREMENT = 94
AVG_ROW_LENGTH = 5461
CHARACTER SET latin1
COLLATE latin1_swedish_ci;

CREATE TABLE operators (
  id int(11) NOT NULL AUTO_INCREMENT,
  name varchar(50) DEFAULT NULL,
  username varchar(255) DEFAULT NULL,
  password varchar(255) DEFAULT NULL,
  PRIMARY KEY (id),
  UNIQUE INDEX username (username)
)
ENGINE = INNODB
AUTO_INCREMENT = 5
AVG_ROW_LENGTH = 16384
CHARACTER SET latin1
COLLATE latin1_swedish_ci;

CREATE TABLE payments_audit (
  Id int(11) NOT NULL AUTO_INCREMENT,
  CustomerId int(11) DEFAULT NULL,
  DateCreated timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  Amount decimal(8, 2) NOT NULL DEFAULT 0.00,
  Method text NOT NULL,
  PRIMARY KEY (Id),
  UNIQUE INDEX Id (Id)
)
ENGINE = INNODB
AUTO_INCREMENT = 2088
AVG_ROW_LENGTH = 55
CHARACTER SET latin1
COLLATE latin1_swedish_ci;

CREATE TABLE payments (
  Id int(11) NOT NULL AUTO_INCREMENT,
  CustomerId int(11) DEFAULT NULL,
  DateCreated timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  Amount decimal(8, 2) NOT NULL DEFAULT 0.00,
  Method text NOT NULL,
  PRIMARY KEY (Id),
  CONSTRAINT FK_payments_customers_Id FOREIGN KEY (CustomerId)
  REFERENCES customers (Id) ON DELETE NO ACTION ON UPDATE NO ACTION
)
ENGINE = INNODB
AUTO_INCREMENT = 60
AVG_ROW_LENGTH = 16384
CHARACTER SET latin1
COLLATE latin1_swedish_ci;

DELIMITER $$

CREATE
DEFINER = 'root'@'localhost'
TRIGGER balancedelete
AFTER DELETE
ON invoicelines
FOR EACH ROW
BEGIN
  UPDATE customers
  SET customers.Balance = (SELECT
    SUM(invoicelines.Amount)
  FROM invoicelines
  WHERE InvoiceId = InvoiceId)
  WHERE Id = Id;

  UPDATE invoices
  SET Amount = Amount - OLD.amount
  WHERE id = OLD.InvoiceId;

  UPDATE customers
  SET Balance = Balance - (SELECT
    SUM(Amount)
  FROM payments p
  WHERE p.CustomerId = p.CustomerId)
  WHERE Id = Id;

  INSERT INTO payments_audit (CustomerId, DateCreated, Amount)
    SELECT
      payments.CustomerId,
      payments.DateCreated,
      payments.Amount
    FROM payments
    WHERE Id = Id;

  INSERT INTO invoicelines_audit (InvoiceId, Description, DateCreated, Amount)
    SELECT
      invoicelines.InvoiceId,
      invoicelines.Description,
      invoicelines.DateCreated,
      invoicelines.Amount
    FROM invoicelines
    WHERE Id = Id;
END
$$

CREATE
DEFINER = 'root'@'localhost'
TRIGGER balanceinsert
AFTER INSERT
ON invoicelines
FOR EACH ROW
BEGIN
  UPDATE customers
  SET customers.Balance = (SELECT
    SUM(invoicelines.Amount)
  FROM invoicelines
  WHERE InvoiceId = InvoiceId)
  WHERE Id = Id;

  UPDATE invoices
  SET Amount = Amount + NEW.amount
  WHERE id = NEW.InvoiceId;

  UPDATE customers
  SET Balance = Balance - (SELECT
    SUM(Amount)
  FROM payments p
  WHERE p.CustomerId = p.CustomerId)
  WHERE Id = Id;

  INSERT INTO payments_audit (CustomerId, DateCreated, Amount)
    SELECT
      payments.CustomerId,
      payments.DateCreated,
      payments.Amount
    FROM payments
    WHERE Id = Id;

  INSERT INTO invoicelines_audit (InvoiceId, Description, DateCreated, Amount)
    SELECT
      invoicelines.InvoiceId,
      invoicelines.Description,
      invoicelines.DateCreated,
      invoicelines.Amount
    FROM invoicelines
    WHERE Id = Id;
END
$$

CREATE
DEFINER = 'root'@'localhost'
TRIGGER balanceupdate
AFTER UPDATE
ON invoicelines
FOR EACH ROW
BEGIN
  UPDATE customers
  SET customers.Balance = (SELECT
    SUM(invoicelines.Amount)
  FROM invoicelines
  WHERE InvoiceId = InvoiceId)
  WHERE Id = Id;

  UPDATE invoices
  SET Amount = Amount + NEW.amount
  WHERE id = NEW.InvoiceId;

  UPDATE customers
  SET Balance = (SELECT
    SUM(Amount)
  FROM payments p
  WHERE p.Id = NEW.Id)
  WHERE Id = NEW.ID;


  INSERT INTO invoicelines_audit (InvoiceId, Description, DateCreated, Amount)
    SELECT
      invoicelines.InvoiceId,
      invoicelines.Description,
      invoicelines.DateCreated,
      invoicelines.Amount
    FROM invoicelines
    WHERE Id = Id;
END
$$

CREATE
DEFINER = 'root'@'localhost'
TRIGGER paymentdelete
AFTER DELETE
ON payments
FOR EACH ROW
BEGIN
  UPDATE customers
  SET Balance =
  ((SELECT
    SUM(invoicelines.Amount)
  FROM invoicelines
  WHERE InvoiceId = InvoiceId) - (SELECT
    SUM(Amount)
  FROM payments
  WHERE CustomerId = CustomerId))
  WHERE Id = Id;

  INSERT INTO payments_audit (CustomerId, DateCreated, Amount, Method)
    SELECT
      payments.CustomerId,
      payments.DateCreated,
      payments.Amount,
      payments.Method
    FROM payments
    WHERE Id = Id;
END
$$

CREATE
DEFINER = 'root'@'localhost'
TRIGGER paymentinsert
AFTER INSERT
ON payments
FOR EACH ROW
BEGIN
  UPDATE customers
  SET Balance =
  ((SELECT
    SUM(invoicelines.Amount)
  FROM invoicelines
  WHERE InvoiceId = InvoiceId) - (SELECT
    SUM(Amount)
  FROM payments
  WHERE CustomerId = CustomerId))
  WHERE Id = Id;

  INSERT INTO payments_audit (CustomerId, DateCreated, Amount, Method)
    SELECT
      payments.CustomerId,
      payments.DateCreated,
      payments.Amount,
      payments.Method
    FROM payments
    WHERE Id = Id;
END
$$

CREATE
DEFINER = 'root'@'localhost'
TRIGGER paymentupdate
AFTER UPDATE
ON payments
FOR EACH ROW
BEGIN
  UPDATE customers
  SET Balance =
  ((SELECT
    SUM(invoicelines.Amount)
  FROM invoicelines
  WHERE InvoiceId = InvoiceId) - (SELECT
    SUM(Amount)
  FROM payments
  WHERE CustomerId = CustomerId))
  WHERE Id = Id;

  INSERT INTO payments_audit (CustomerId, DateCreated, Amount, Method)
    SELECT
      payments.CustomerId,
      payments.DateCreated,
      payments.Amount,
      payments.Method
    FROM payments
    WHERE Id = Id;
END
$$

DELIMITER ;

CREATE OR REPLACE
DEFINER = 'root'@'localhost'
VIEW statements
AS
SELECT
  `customers`.`Id` AS `customer_Id`,
  `customers`.`Name` AS `Name`,
  `customers`.`Address` AS `Address`,
  `payments`.`Method` AS `Method`,
  `payments`.`Amount` AS `payment_amount`,
  `payments`.`DateCreated` AS `DateCreated`,
  `payments`.`CustomerId` AS `CustomerId`,
  `payments`.`Id` AS `Id`,
  `invoices`.`Amount` AS `Amount`,
  `invoices`.`Description` AS `Description`
FROM ((`invoices`
  JOIN `customers`
    ON ((`invoices`.`CustomerId` = `customers`.`Id`)))
  JOIN `payments`
    ON ((`payments`.`CustomerId` = `customers`.`Id`)));

1 个答案:

答案 0 :(得分:0)

这不是一个完整的解决方案,但我希望它能帮助您:

如果要更新触发器内的某些内容,则可以使用包含操作前后记录的NEW和OLD值。 对于invoicelines上的DELETE,您可以使用NEW.invoiceID连接到发票。 然后,您必须根据customerID字段找到该发票并更新客户。然后从该customerID到达付款。

以下是一些代码:

sqlfiddle demo

(请注意,在sqlfiddle中,DELIMITER和DEFINER ='root'@'localhost'必须被剥离)

DELIMITER $$

CREATE DEFINER = 'root'@'localhost'
TRIGGER balancedelete AFTER DELETE ON invoicelines
FOR EACH ROW
BEGIN

  UPDATE invoices
  SET Amount = Amount - OLD.amount
  WHERE id = OLD.InvoiceId;

  UPDATE customers
  SET Balance = Balance - OLD.amount
  WHERE Id = (SELECT customerID FROM invoices WHERE id = OLD.InvoiceId);

  UPDATE payments
  SET amount = amount - OLD.amount
  WHERE customerID = (SELECT customerID FROM invoices WHERE id = OLD.InvoiceId);

  INSERT INTO payments_audit (CustomerId, DateCreated, Amount)
    SELECT
      payments.CustomerId,
      payments.DateCreated,
      payments.Amount
    FROM payments
    WHERE customerID = (SELECT customerID FROM invoices WHERE id = OLD.InvoiceId);

  INSERT INTO invoicelines_audit (InvoiceId, Description, DateCreated, Amount)
    VALUES(
      OLD.InvoiceId,
      OLD.Description,
      OLD.DateCreated,
      OLD.Amount);
END
$$

CREATE DEFINER = 'root'@'localhost' TRIGGER balanceinsert
AFTER INSERT ON invoicelines
FOR EACH ROW
BEGIN
  UPDATE invoices
  SET Amount = Amount + NEW.amount
  WHERE id = NEW.InvoiceId;

  UPDATE customers
  SET Balance = Balance + NEW.amount
  WHERE Id = (SELECT customerID FROM invoices WHERE id = NEW.InvoiceId);

  UPDATE payments
  SET amount = amount + NEW.amount
  WHERE customerID = (SELECT customerID FROM invoices WHERE id = NEW.InvoiceId);

  INSERT INTO payments_audit (CustomerId, DateCreated, Amount)
    SELECT
      payments.CustomerId,
      payments.DateCreated,
      payments.Amount
    FROM payments
    WHERE customerID = (SELECT customerID FROM invoices WHERE id = NEW.InvoiceId);

  INSERT INTO invoicelines_audit (InvoiceId, Description, DateCreated, Amount)
    VALUES(
      NEW.InvoiceId,
      NEW.Description,
      NEW.DateCreated,
      NEW.Amount);
END
$$

CREATE DEFINER = 'root'@'localhost' TRIGGER balanceupdate
AFTER UPDATE ON invoicelines
FOR EACH ROW
BEGIN
  UPDATE invoices
  SET Amount = Amount + NEW.amount - OLD.amount
  WHERE id = NEW.InvoiceId;

  UPDATE customers
  SET Balance = Balance + NEW.amount - OLD.amount
  WHERE Id = (SELECT customerID FROM invoices WHERE id = NEW.InvoiceId);

  UPDATE payments
  SET amount = amount + NEW.amount - OLD.amount
  WHERE customerID = (SELECT customerID FROM invoices WHERE id = NEW.InvoiceId);

  INSERT INTO payments_audit (CustomerId, DateCreated, Amount)
    SELECT
      payments.CustomerId,
      payments.DateCreated,
      payments.Amount
    FROM payments
    WHERE customerID = (SELECT customerID FROM invoices WHERE id = NEW.InvoiceId);

  INSERT INTO invoicelines_audit (InvoiceId, Description, DateCreated, Amount)
    VALUES(
      NEW.InvoiceId,
      NEW.Description,
      NEW.DateCreated,
      NEW.Amount);
END
$$

对于付款中的触发器,您可以使用相同的理由来更新所需的表格。