2014-01-27 37 views
1

我只是在自学SQL和PLSQL,并且没有太多麻烦调试常规SQL,但我试图调用PLSQL函数抛出错误,我无法从Oracle文档和其他在线资源中找出错误。我正在使用Oracle SQL-Developer。 我已经试过这些,但他们也没有什么帮助在这种情况下:PLSQL - 调用函数用char(1)和数字变量计算

How to return a record from an existing table from an Oracle PL/SQL function?

Writing a function in plsql

Oracle PLSQL function call into a second function

Can't seem to subract two numbers in a PLSQL function

我试着写相同功能的两种不同的方式练习:

Create Function Calc_Tax 
(Quantity IN Number,Unit_Price IN Number,Taxable IN VarChar2) 
    Return Number IS amt Number; 
Declare 
price := Quantity * Unit_Price; 
Begin 
    IF Taxable = 'Y' THEN 
    amt := price + 0.06 * price; 
    ELSE 
    amt := price; 
    END IF; 
    Return amt; 
End; 

-- or -- 

Create Or Replace Function Calc_Tax 
(Quantity IN Number,Unit_Price IN Number,tax IN Sale_Item.Taxable%TYPE) 
    Return Number IS amt Number; 
    Declare 
    price := Quantity * Unit_Price; 
    Begin 
    IF tax = 'Y' THEN 
    amt := price + 0.06 * price; 
    ELSE 
    amt := price; 
    END IF; 
    Return amt; 
End; 

我在将'tax'参数声明为varchar2(1)时遇到了一些麻烦,所以我只留下了varchar2,其中文档似乎是默认的1个空格(如果我阅读的话)。当然,我宁愿这样做,并明确声明varchar的大小。

这是我怎样,我称之为:

DECLARE 
    g_last Guest.First_Name%type := 'Richard'; 
    g_last Guest.Last_Name%type := 'Wharton'; 
    g_id Guest.Guest_ID%type; 
    s_g_id Stay.Guest_ID%type; 
    sho_id Stay.Hotel_ID%type; 
    h_id Hotel.Hotel_ID%type; 
    h_name Hotel.Hotel_Name%type; 
    i_id Sale_Item.Item_ID%type; 
    i_name Sale_Item.Item_Name%type; 
    i_tax Sale_Item.Taxable%type; 
    cs_id Charge.Stay_ID%type; 
    c_date Charge.Trans_Date%type; 
    c_quant Charge.Quantity%type; 
    c_uprice Charge.Unit_Price%type; 
BEGIN 
    SELECT H.Hotel_ID, H.Hotel_Name,C.Item_ID, Item_Name, C.Trans_Date, C.Quantity, 
    C.Unit_Price,Taxable INTO h_id,h_name,i_id,i_name,c_date,c_quant,c_uprice 
    FROM Hotel H,Charge C Where cs_id = (Select Stay_ID From Stay Where Guest_ID = 
    (Select Guest_ID From Guest Where First_Name='Richard' And Last_Name='Wharton')); 
    --WHERE id = c_id; 

    dbms_output.put_line 
    ('Guest ' ||g_first || g_last || ' bought ' || i_name || ' with tax ' || Calc_Tax 

(c_quant,c_uprice,i_tax)); 
END; 

而且它抛出错误:

Error(18,1): PLS-00103: Encountered the symbol "DECLARE" 
Error(43,4): PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:  (begin case declare end exception exit for goto if loop mod null pragma raise return select update while with <an identifier> <a double-quoted delimited-identifier> <a bind variable> << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge 

这里的模式:

enter image description here

我刚学现在,所以我确信任何初级SQL程序员都可以快速向我展示我要去哪里NG。

+0

申报。是一个sql * plus命令,而不是一个PL/SQL关键字,你引用的链接显示了一个简单的函数的例子,它具有正确的语法。 – OldProgrammer

+0

@OldProgrammer DECLARE是PL/SQL的! –

+3

@OldProgrammer - DECLARE不是一个SQL * Plus命令,它是[PL/SQL块]的一部分(http ://docs.oracle.com/cd/E11882_01/appdev.112/e25519/overview.htm#i8859)。您可以将它用作任何地方的动画块的一部分,并作为触发器声明的一部分。但它对函数声明无效,否。 –

回答

3

您不要在过程或函数中使用DECLARE - 而是使用AS关键字来代替变量声明“block”。

你也不能把参数的约束(例如,你可以有VARCHAR2但不VARCHAR2(10) - See Oracle docs

你也应该不会有分号以下的return语句

Create Function Calc_Tax (Quantity IN Number, Unit_Price IN Number, Taxable IN VarChar2) 
Return Number 
AS 
    My_Variable VARCHAR2(2000); 
BEGIN 
    -- code 
END Calc_Tax; 
+0

添加到您的答案中,INTO部分也缺少一个变量(纳税)!还值得一提的是。如果SELECT返回多于一行,我们需要将其作为隐式/显式游标进行循环。 –