使用 Oracle SQL 脚本通过计算(总发票)更新多个表中的记录

发布于 2024-12-17 16:20:31 字数 1850 浏览 0 评论 0原文

我有一个 SERVICE 表,将服务金额存储在一个表中,然后链接到一个 LINE 表,该表连接到 INVOICE

我想创建一个触发器,根据 SERVICE 表中的金额更新每行的总计,最后更新 INVOICE 表中发票的运行总计。

我陷入了 UPDATE 命令以将 20.00 更新到 LINE 表和 SERVICE 表中。

我怎样才能创建这个UPDATE

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');

I have a SERVICE table that stores amounts for services in one table then links to a LINE table which connects to an INVOICE.

I want to create a trigger that updates the total per line based on the amount in the SERVICE table and finally a running total for the invoice in the INVOICE table.

I'm stuck on the UPDATE command to get the 20.00 to update into the LINE table and SERVICE table.

How can I create this UPDATE?

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');

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

£烟消云散 2024-12-24 16:20:31

一般来说,我会对行或发票等表中的计算列感到有点不舒服。通常,当计算结果不等于存储结果时,数据完整性问题就会开始蔓延。

您可以使用一个查询来按需计算 LinePrice,而不是使用 LINE.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 实例,因此您需要验证语法):

    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;

这只是尝试在插入时执行 LinePrice。您还需要增加 InvoiceTotal。并且您需要关注更新(减去:旧总和,并添加:新总和)和删除场景(减去:旧总和)。

As a general rule, I would be a bit uncomfortable with computed columns in a table such as Line or Invoice. Often data integrity issues start creeping in where the the computed result does not equal the stored result.

Rather than having the LINE.LinePrice column, you could have a query that will compute the LinePrice on demand:

    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

Similar with the INVOICE.InvoiceTotal you could do a query something like this:

    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

If you go this route, then you also have to think about what happens when the service price changes. If you print old invoices, are you going to be computing new totals or did you want to use the historical values to compute what the invoice was in the past? Probably the latter, so changes in the Service table would need to be effective dated having the date as part of the key. Then you can keep track of historical prices.

But I also understand wanting a fixed, static value if the invoice is done (usually an archive document). If you want to go the trigger route, the trigger may look something like this (I don't have an Oracle instance available, so you will need to verify syntax):

    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;

This is just trying to do the LinePrice on Insert. You would need to increase the InvoiceTotal as well. And you would need to look after the UPDATE (subtract :old sum, and add :new sum) and DELETE scenarios (subtract :old sum).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文