使用Oracle SQL脚本通过计算(总发票)跨多个表更新记录
我有一个使用Oracle SQL脚本通过计算(总发票)跨多个表更新记录,sql,oracle,oracle-sqldeveloper,Sql,Oracle,Oracle Sqldeveloper,我有一个服务表,它将服务金额存储在一个表中,然后链接到一个行表,该表连接到一个发票 我想创建一个触发器,根据服务表中的金额更新每行的总额,最后在发票表中更新发票的运行总额 我被更新命令卡住了,无法将20.00更新到行表和服务表中 如何创建此更新 CREATE TABLE SERVICE ( ServiceID char(6) NOT NULL, Description varchar(50) NOT NULL, Price
服务
表,它将服务金额存储在一个表中,然后链接到一个行
表,该表连接到一个发票
我想创建一个触发器,根据服务
表中的金额更新每行的总额,最后在发票
表中更新发票的运行总额
我被更新命令卡住了,无法将20.00更新到行
表和服务
表中
如何创建此更新
CREATE TABLE SERVICE
(
ServiceID char(6) NOT NULL,
Description varchar(50) NOT NULL,
Price decimal(6,2) NOT NULL,
CONSTRAINT PK_ServiceID PRIMARY KEY (ServiceID)
);
CREATE TABLE INVOICE
(
InvoiceID char(6) NOT NULL,
InvoiceTotal LONG,
CustomerID char(6) NOT NULL,
EmployeeID char(6) NOT NULL,
InvoiceDate date NOT NULL,
Notes varchar(200),
CONSTRAINT PK_Invoice PRIMARY KEY (InvoiceID),
CONSTRAINT FK_CUSTOMER FOREIGN KEY (CustomerID) REFERENCES CUSTOMER(CustomerID),
CONSTRAINT FK_EMPLOYEE FOREIGN KEY (EmployeeID) REFERENCES EMPLOYEE(EmployeeID)
);
CREATE TABLE LINE (
LineID char(6) NOT NULL,
LineQty int NOT NULL,
LinePrice decimal(6,2),
InvoiceID char(6) NOT NULL,
ServiceID char(6) NOT NULL,
CONSTRAINT PK_LineID PRIMARY KEY (LineID),
CONSTRAINT FK_INVOICE FOREIGN KEY (InvoiceID) REFERENCES INVOICE(InvoiceID),
CONSTRAINT FK_SERVICE FOREIGN KEY (ServiceID) REFERENCES SERVICE(ServiceID)
);
INSERT INTO SERVICE(ServiceID, Description, Price)
VALUES('SE0001', 'Press Shirt', 20.00);
INSERT INTO SERVICE(ServiceID, Description, Price)
VALUES('SE0002', 'Press Slacks', 15.00);
INSERT INTO INVOICE(InvoiceID, CustomerID, EmployeeID, InvoiceDate)
VALUES('IN0001', 'CU0001', 'EE0001', '01-SEP-2011');
INSERT INTO LINE(LineID, LineQty, InvoiceID, ServiceID)
VALUES('LI0001', '2', 'IN0001', 'SE0001');
一般来说,我对表格中的计算列(如Line或Invoice)会有点不舒服。通常,当计算结果与存储结果不相等时,数据完整性问题开始蔓延 不必使用LINE.LinePrice列,您可以使用一个查询按需计算LinePrice:
SELECT l.LineID, l.LineQty, l.LineQty * s.Price AS LinePrice, l.InvoiceID, l.ServiceID
FROM LINE l, SERVICE s
WHERE s.ServiceID = l.ServiceID
与INVOICE.InvoiceTotal类似,您可以执行如下查询:
SELECT i.InvoiceID, SUM(x.LinePrice) AS InvoiceTotal
FROM INVOICE i
,(SELECT l.InvoiceID, l.LineQty * s.Price AS LinePrice
FROM LINE l, SERVICE s
WHERE s.ServiceID = l.ServiceID) x
WHERE i.InvoiceID = x.InvoiceID
GROUP BY i.InvoiceID
如果你走这条路,那么你还必须考虑当服务价格改变时会发生什么。如果打印旧发票,您是要计算新的总额,还是要使用历史值来计算过去的发票?可能是后者,因此服务表中的更改需要注明生效日期,并将日期作为键的一部分。然后你可以跟踪历史价格
但我也理解,如果完成了发票(通常是存档文档),则需要一个固定的静态值。如果您想执行触发器路径,触发器可能看起来像这样(我没有可用的Oracle实例,因此您需要验证语法):
这只是尝试在插入时执行LinePrice。您还需要增加发票总额。您需要注意更新(减:旧和,加:新和)和删除场景(减:旧和)。谢谢Glenn,这是可行的,我理解您对静态存储值的担忧。我会考虑的。也许只是通过我的PHP代码更新总数,而不是使用触发器。
CREATE OR REPLACE TRIGGER line_insert
BEFORE INSERT ON line
FOR EACH ROW
BEGIN
SELECT :new.LineQty * Price
INTO :new.LinePrice
FROM Service
WHERE serviceID = :new.ServiceID;
END;