2017-03-19 4 views
0
CREATE OR REPLACE FUNCTION ComputeFreight(subtotal NUMBER) 
RETURN NUMBER 
IS 
freightCharge NUMBER; 
BEGIN 
    IF subtotal <= 15000 THEN 
    freightCharge := (subtotal * .10); 
    ELSIF subtotal > 15000 THEN 
    freightCharge := (subtotal * .15); 
    RETURN(freightCharge); 
    END IF; 
END; 

DECLARE 
    subtotal NUMBER := 15000; 
BEGIN 
    DBMS_OUTPUT.PUT_LINE(ComputeFreight(subtotal)); 
END; 

Ich weiß nicht, was ist falsch mit meinem Code, aber es zeigt immer diese Fehlermeldung:Funktion in PL SQL (Oracle) Fehler

Invalid statement

Invalid statement

ORA-06503: PL/SQL: Function returned without value ORA-06512: at "SQL_JQQXUMCMKFMRHRPZCYFNBEVTN.COMPUTEFREIGHT", line 12 ORA-06512: at line 4 ORA-06512: at "SYS.DBMS_SQL", line 1721

+0

In Ihrem Beispiel ist NUMBER 15000. In diesem Fall wird der erste Zweig der IF-Anweisung als wahr ausgewertet; frachtgutschrift erhält den Wert 1500, und die IF-Anweisung wird beendet. Die RETURN-Anweisung wird nie erreicht. Sie könnten eine RETURN-Anweisung im ersten Zweig von IF hinzufügen, aber im Allgemeinen sind Funktionen mit mehr als einer RETURN-Anweisung "Spaghetti-Code" (Code, der schwer zu verstehen und zu pflegen ist). Die in der GurV-Lösung vorgeschlagene Option ist weit überlegen. Ich nehme auch an, dass dies "Praxis" für IF-Anweisungen ist; du brauchst nicht wirklich eine für dieses Problem. – mathguy

Antwort

3

Die return-Anweisung außerhalb der if-else sein sollte:

CREATE OR REPLACE FUNCTION ComputeFreight(subtotal NUMBER) 
RETURN NUMBER 
IS 
freightCharge NUMBER; 
BEGIN 
    IF subtotal <= 15000 THEN 
     freightCharge := (subtotal * .10); 
    ELSIF subtotal > 15000 THEN 
     freightCharge := (subtotal * .15); 
    END IF; 
    RETURN(freightCharge); -- here 
END; 
2

Wenn dies für die IF-Anweisung praktiziert wird, ist das in Ordnung (mit GurVs Vorschlag der Platzierung der RETURN-Anweisung). Wenn Sie dies jedoch in einer Produktion benötigen, möchten Sie vielleicht die Funktion vereinfachen und effizienter machen. Etwas wie dieses:

CREATE OR REPLACE FUNCTION ComputeFreight(subtotal NUMBER) 
RETURN NUMBER 
IS 
BEGIN 
    RETURN subtotal * (CASE WHEN subtotal <= 15000 THEN 0.1 ELSE 0.15 END); 
END;