0

我有一个触发器,更新客户部分在更新上正常工作。我希望有人帮助我更正剩余部分,并向我展示此代码在更新/插入/删除触发器中正确工作的格式。

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

我现在到处都感到困惑——可能是因为我已经有 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`)));
4

1 回答 1

0

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

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

这是一些代码:

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
$$

对于 Payments 中的触发器,您执行相同的理由来更新所需的表。

于 2013-10-25T00:28:27.950 回答