【问题标题】:I am having trouble calculating the correct total of an invoice PL/SQL我在计算发票 PL/SQL 的正确总数时遇到问题
【发布时间】:2013-11-27 17:00:44
【问题描述】:

我正在尝试创建一个函数和程序来计算特定汽车服务的总成本。列出零件的所有单个成本和服务成本,并生成更新发票表的总计。

我目前正在经历服务成本的双重收费,我认为逻辑存在问题,因为所有服务的总成本都显示出来了。我想限制每项特定服务的零件成本。

这是我在 SQL+ 上创建的数据库的演示版本。

SERVICE

CREATE TABLE SERVICE
(SERVICE_ID VARCHAR2 (3) PRIMARY KEY,       
DATE_OF_SERVICE DATE NOT NULL,
TIME VARCHAR2 (8)NOT NULL,              
STAFF_RECORDED VARCHAR2 (3)NOT NULL,            
STAFF_SERVICING VARCHAR2 (3)NOT NULL,           
SERVICE_TYPE_ID VARCHAR2 (1)NOT NULL,           
CAR_ID VARCHAR2 (3)NOT NULL,
BRANCH_ID VARCHAR2 (3)NOT NULL);

INSERT INTO SERVICE VALUES ('01', '14/JAN/2013', '11.15', '01', '06', '1', '01','01');
INSERT INTO SERVICE VALUES ('02','14/JAN/2013', '11.15', '01', '06', '1', '01','01');


PART_SERVICE

CREATE TABLE PART_SERVICE
(PART_ID VARCHAR2 (3),
SERVICE_ID VARCHAR2 (3));

INSERT INTO PART_SERVICE VALUES ('01', '01');
INSERT INTO PART_SERVICE VALUES ('02', '01');

INVOICE

CREATE TABLE INVOICE
(INVOICE_ID VARCHAR2 (3) PRIMARY KEY,               
CUSTOMER_ID VARCHAR2 (3),           
SERVICE_ID VARCHAR2 (3),                            
TOTAL_COST NUMBER (10,2));

INSERT INTO INVOICE VALUES ('01', '01', '01',NULL);

CREATE TABLE SERVICE_TYPE
(SERVICE_TYPE_ID VARCHAR2 (1) PRIMARY KEY,  
SERVICE_NAME VARCHAR2 (15)NOT NULL,
SERVICE_COST NUMBER (5,2)NOT NULL);

INSERT INTO SERVICE_TYPE VALUES ('1', 'FULL SERVICE', 140.00);

PART

CREATE TABLE PART
(PART_ID VARCHAR2(3) PRIMARY KEY,           
PART_NAME VARCHAR2 (20)NOT NULL,
PART_TYPE VARCHAR2 (20)NOT NULL,
PART_PRICE NUMBER (5,2)NOT NULL);

INSERT INTO PART VALUES ('01', 'ABS sensors', 'Electrical', '200.00');
INSERT INTO PART VALUES ('02', 'Light bulbs', 'Electrical', '50.00');

SET SERVEROUTPUT ON
SET ECHO ON

CREATE OR REPLACE FUNCTION INVOICE_TOTAL
(i_invoice invoice.invoice_id%TYPE)

RETURN NUMBER
IS
v_invoice_total invoice.total_cost%TYPE;

BEGIN

SELECT SUM(NVL(PART_PRICE+SERVICE_COST,0))
INTO v_invoice_total
FROM SERVICE, PART, SERVICE_TYPE, PART_SERVICE
WHERE SERVICE_TYPE.SERVICE_TYPE_ID = SERVICE.SERVICE_TYPE_ID
AND PART.PART_ID = PART_SERVICE.PART_ID
AND SERVICE.SERVICE_ID = PART_SERVICE.SERVICE_ID
AND SERVICE.SERVICE_ID = i_invoice;

IF v_invoice_total IS NULL THEN
    v_invoice_total := 0;
END IF;

RETURN v_invoice_total;

END;
/

CREATE OR REPLACE PROCEDURE TOTALCOST
AS
CURSOR c_invoice
IS
SELECT SERVICE_ID
FROM SERVICE;

v_invoice       invoice.invoice_id%TYPE;
v_invoice_total_cost    invoice.total_cost%TYPE;

BEGIN
OPEN c_invoice;
LOOP
FETCH c_invoice INTO v_invoice;
EXIT WHEN c_invoice%NOTFOUND;

  v_invoice_total_cost := INVOICE_TOTAL(v_invoice);

UPDATE invoice
SET total_cost = v_invoice_total_cost
WHERE invoice_id = v_invoice;

DBMS_OUTPUT.PUT_LINE('PART PRICE:'|| TO_CHAR(v_invoice_total_cost));

END LOOP;

DBMS_OUTPUT.PUT_LINE('Total = '|| TO_CHAR(v_invoice_total_cost));
CLOSE c_invoice;
END;
/

exec TOTALCOST;

实际输出为:

PART PRICE:530
PART PRICE:0
PART PRICE:0
PART PRICE:0
PART PRICE:0
Total = 0

我想得到什么:

SERVICE = '01'
PART PRICE = 200
PART PRICE = 50
SERVICE PRICE = 140

Total Price: 390

【问题讨论】:

  • 请显示预期输出与实际输出的对比。
  • 我已经用实际输出和预期更新了问题
  • 将时间部分存储为日期的一部分。
  • tldr.您是否尝试过调试或至少将有效的部分与无效的部分隔离开来?

标签: sql oracle stored-procedures plsql


【解决方案1】:

我认为问题出在您的种子数据中。你有这个:

CREATE TABLE PART_SERVICE
(PART_ID VARCHAR2 (3),
SERVICE_ID VARCHAR2 (3));

INSERT INTO PART_SERVICE VALUES ('01', '01');
INSERT INTO PART_SERVICE VALUES ('02', '01');

但我认为第二个插入是转置值,而您的意思是这样做:

INSERT INTO PART_SERVICE VALUES ('01', '01');
INSERT INTO PART_SERVICE VALUES ('01', '02'); -- swapped values.

【讨论】:

  • 我打算展示在服务“01”中使用了两个部分,即“01”部分和“02”部分。
【解决方案2】:

请将函数中的 JOIN 更改为如下所示,这样更具可读性。

因为您的查询将有两个PARTS,所以如果您这样写,SERVICE_TYPE 表行将被添加两次(解释额外的 140)。
您的功能必须类似于

SELECT x.PartCost + st.SERVICE_COST
INTO v_invoice_total
FROM SERVICE_TYPE st
JOIN (
    SELECT SUM(PART_PRICE) [PartCost], s.SERVICE_ID, s.SERVICE_TYPE_ID
    FROM SERVICE s
        JOIN PART_SERVICE ps ON s.SERVICE_ID = ps.SERVICE_ID
        JOIN PART p ON ps.PART_ID = p.PART_ID
    GROUP BY s.SERVICE_ID, s.SERVICE_TYPE_ID
    ) as x ON x.SERVICE_TYPE_ID = st.SERVICE_TYPE_ID

【讨论】:

    【解决方案3】:

    Fell/sql 要求你有一个大的fall,如果你有一个小的 fall 就做不到

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-11
      • 2013-09-02
      • 2022-10-06
      • 1970-01-01
      相关资源
      最近更新 更多