2015-05-13 53 views
0

我正在創建一個存儲過程,該存儲過程需要輸入一個id和一個開始日期和結束日期,然後返回該範圍內的行程。我一直在尋找在Oracle文檔,我覺得我很接近,但得到了一些錯誤尚未:在Oracle中設置存儲過程

CREATE or replace PROCEDURE chg_per_aircraft 
    (p_aircraft_id IN RCC_AIRCRAFT.aircraft_id, 
    p_start_date IN date, 
    p_end_date IN date, 
    p_ttl_chg_per_acft OUT INTEGER) 

AS            
BEGIN 
    SELECT RCC_AIRCRAFT.aircraft_id, 
     SUM(RCC_CHARTER.distance * RCC_MODEL.charge_per_mile) ttl_chg 
    INTO 
     p_aircraft_id, 
     p_ttl_chg_per_acft 
FROM RCC_AIRCRAFT 
full join RCC_CHARTER 
on RCC_CHARTER.aircraft_id = RCC_AIRCRAFT.aircraft_id 
left join RCC_MODEL 
on RCC_MODEL.model_code = RCC_AIRCRAFT.model_code 
Where RCC_CHARTER.trip_date > p_start_date and RCC_CHARTER.trip_date < p_end_date 
group by RCC_AIRCRAFT.aircraft_id; 


SYS.DBMS_OUTPUT.PUT_LINE(ttl_chg); 
end; 
+0

你會得到什麼錯誤? –

+0

運行此查詢,我的錯誤是:'PL/SQL:編譯單元分析終止'和'PLS-00488:RCC_AIRCRAFT.Aircraft_ID必須爲' – dreamerdiver

+0

SYS.DBMS_OUTPUT.PUT_LINE(ttl_chg);作爲存儲過程運行時不會產生任何輸出。在終端上運行pl/sql時,您可以獲得輸出。 –

回答

2

你的第一個錯誤的參數定義:

p_aircraft_id IN RCC_AIRCRAFT.aircraft_id 

應該

p_aircraft_id IN RCC_AIRCRAFT.aircraft_id%TYPE 

但是,然後你選擇INTO p_aircraft_id,它被聲明爲一個IN參數,所以你不能將它設置爲一個新的值。這是你想要傳入的變量還是你想要跳出的值?作爲調用者隨日期提供的東西,它會更有意義,但是您需要將它用作select語句中的過濾器。如果有多個飛機編號 - 如果它只有日期限制 - 那麼你會得到多個結果,無論如何這將是一個too_many_rows錯誤。

您的輸出將僅對設置爲處理它的會話可見,因此對於調用者來說可能更有意義;但在任何情況下,應該是:

DBMS_OUTPUT.PUT_LINE(p_ttl_chg_per_acft); 

...爲ttl_chg只存在一個列別名,而不是一個PL/SQL變量。

如果您傳遞在飛機ID,你可能會想是這樣的:

CREATE or replace PROCEDURE chg_per_aircraft 
    (p_aircraft_id IN RCC_AIRCRAFT.aircraft_id%TYPE, 
    p_start_date IN date, 
    p_end_date IN date, 
    p_ttl_chg_per_acft OUT INTEGER) 
AS            
BEGIN 
    SELECT SUM(RCC_CHARTER.distance * RCC_MODEL.charge_per_mile) ttl_chg 
    INTO p_ttl_chg_per_acft 
    FROM RCC_AIRCRAFT 
    JOIN RCC_CHARTER 
    ON RCC_CHARTER.aircraft_id = RCC_AIRCRAFT.aircraft_id 
    JOIN RCC_MODEL 
    ON RCC_MODEL.model_code = RCC_AIRCRAFT.model_code 
    WHERE RCC_CHARTER.trip_date > p_start_date 
    AND RCC_CHARTER.trip_date < p_end_date 
    AND RCC_AIRCRAFT.aircraft_id = p_aircraft_id 
    GROUP BY RCC_AIRCRAFT.aircraft_id; 

    -- just to debug! 
    DBMS_OUTPUT.PUT_LINE(p_ttl_chg_per_acft); 
END; 
/

我也改變爲內部連接,因爲它似乎並不實用,使他們外連接。作爲一種功能,這比程序更有意義;儘管在存儲程序中包裝單個查詢可能是不必要的 - 儘管這看起來像一個任務。

+1

我也懷疑查詢可能會返回多個行,在這種情況下選擇標量變量將是不正確的。我的猜測是應該有一個遊標參與。 –

+1

是的,但如果飛機ID實際上已經被傳入,那麼它會好的,因爲它將按照該單個ID進行分組。 –

+0

我明白我做了錯誤與aircraft_id參數的傳遞。感謝您的幫助。爲了澄清你的輸出聲明,我必須創建另一個pl/sql塊才能在控制檯上得到返回的結果,或者'SET SERVEROUTPUT on'。足夠嗎? – dreamerdiver