0

更新の顧客部分が更新で正しく機能しているトリガーがあります。残りの修正を誰かに手伝ってもらい、更新/挿入/削除トリガーに対してこのコードが正しく機能するための形式を教えてください。

基本的に私がする必要があるのは、挿入/更新/削除のために請求明細と支払いを監査することです。auditlines のエントリは、請求表の金額と顧客の残高を更新する必要があります。未払い残高が調整されるように、支払いを更新する必要があります。

私は今、あちこちで混乱しています-おそらく、この多くのために約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 フィールドに基づいて顧客を更新する必要があります。次に、その顧客 ID から 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
$$

支払いのトリガーについては、必要なテーブルを更新するために同じ理論的根拠を実行します。

于 2013-10-25T00:28:27.950 に答える