Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Oracle SQL脚本通过计算(总发票)跨多个表更新记录_Sql_Oracle_Oracle Sqldeveloper - Fatal编程技术网

使用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;