2013-11-27 31 views
0

我正在嘗試創建一個函數和過程,它計算特定汽車服務的總成本。列出零件的所有單獨成本和服務成本,並生成更新發票表的總計。我在計算髮票的正確總數時遇到了困難PL/SQL

我目前正在經歷服務成本的雙重收費,我認爲所有服務的總成本都顯示出邏輯問題。我想限制每個特定服務的部件成本。

這是我在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 
+0

請出示預期輸出是什麼VS實際產出。 – OldProgrammer

+0

我已經更新了實際輸出和預期的問題 – user3010257

+0

將時間組件存儲爲日期的一部分。 –

回答

0

我認爲問題出在您的種子數據。你有這樣的:

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. 
+0

我打算表明,在服務'01'中有兩個部分,分別是'01'和'02'。 – user3010257

+0

好吧,我的壞。抱歉 – OldProgrammer

0

請改變你的函數中的聯接到如下圖所示,它使它更具可讀性。

因爲你的查詢將有兩個PARTSSERVICE_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 
0

費爾/ SQL需要你有一個大的下跌,如果你有小的降幅大於你不會是能夠做到這一點