2014-05-18 35 views
-2

我有一个示例数据库,我需要编写一个存储过程来打印给定的配方(其中包含的数据库,包括成分和数量 - 所以我需要联接表)PL SQL对象无效错误 - 无法找到源

CREATE OR REPLACE PROCEDURE proc_printrecipe (RecipeName IN Recipe.RecipeTitle%TYPE) 
IS 
    TYPE rec_printrecipe IS RECORD 
    (
    rec_IngName Ingredients.IngredientName%TYPE, 
    rec_Amount Recipe_Ingredients.Amount%TYPE, 
    rec_MeasureDesc Measurements.MeasurementDescription%TYPE, 
) 
    CURSOR cur_printrecipe IS 
    SELECT i.ingredientName, ri.Amount, m.MeasurementDescription FROM Recipes r 
    JOIN Recipe_Ingredients ri ON r.RecipeID = ri.RecipeID 
    JOIN Ingredients i ON ri.IngredientID = i.IngredientID 
    JOIN Measurements m ON ri.MeasureAmountID = m.MeasurementDescription 
    WHERE r.RecipeTitle = RecipeName; 
BEGIN 
    IF NOT cur_printrecipe%ISOPEN THEN 
    OPEN cur_printrecipe; 
    END IF; 

    LOOP 
    FETCH cur_printrecipe INTO rec_printrecipe; 
    EXIT WHEN cur_printrecipe%NOTFOUND; 
    dbms_output.put_line(rec_Amount || ' ' 
          rec_MeasureDesc || ' of ' 
          rec_IngName 
         ); 
    END LOOP; 
END; 
/

-- CALLING THE STORED PROCEDURE 
DECLARE 
recipe recipes.RecipeTitle%TYPE := 'Irish Stew'; 
BEGIN 
    proc_printrecipe(recipe); 
END; 

但脚本输出(带的Oracle SQL Developer 1.1.3)工作给了我: 警告:执行与警告

PROCEDURE proc_printrecipe Compiled. 

Error starting at line 33 in command: 
DECLARE 
recipe recipes.RecipeTitle%TYPE := 'Irish Stew'; 
BEGIN 
    proc_printrecipe(recipe); 
END; 
Error report: 
ORA-06550: Line 4, Column 3: 
PLS-00905: Object COOK.PROC_PRINTRECIPE is invalid 
ORA-06550: Line 4, Column 3: 
PL/SQL: Statement ignored 
06550. 00000 - "line %s, column %s:\n%s" 
*Cause: Usually a PL/SQL compilation error. 
*Action: 

我缺少的是完成?

+0

不要忘记在退出程序之前关闭打开的光标。否则,在将来的某个时刻,你的代码会在内存不足的情况下将数据库取出。 –

回答

1

您可以在过程编译后添加show errors以查看问题,至少在SQL * Plus和SQL Developer中是这样的;或查询user_errors观点:

select * from user_errors 
where type = 'PROCEDURE' 
and name = 'PROC_PRINTRECIPE'; 

但一些明显的错误,你必须在你的记录宣告结束一个逗号;你错过了一个分号;你需要声明类型的实例:

  TYPE rec_printrecipe_type IS RECORD 
  (
    IngName Ingredients.IngredientName%TYPE,  
    Amount Recipe_Ingredients.Amount%TYPE, 
    MeasureDesc Measurements.MeasurementDescription%TYPE 
); 
    rec_printrecipe rec_printrecipe_type; 

你的光标开检查是多余的,因为它不能在这一点上打开;但在程序结束时你应该明确地关闭它。

而你的dbms_output调用直接引用字段而不指定它们所属的记录,并且具有不完整的级联;所以你需要做的:

dbms_output.put_line(rec_printrecipe.Amount || ' ' || 
          rec_printrecipe.MeasureDesc || ' of ' || 
          rec_printrecipe.IngName 
         ); 

你假设谁调用这个就能看到dbms_output缓冲区。希望你已经在做set serveroutput on

user_errors可能还存在其他问题。

SQL Developer现在已经升级到了第4版,因此您可以考虑升级。例如,Codo的答案可能指的是比1.1.3版更现代的东西。

+0

错误输出帮助很大!谢谢你..我已经删除了其他错误,你找到了。还是行不通。很遗憾,我在这里混合使用了德语和英语的错误信息.. – apoc

+0

好..显然这些错误在这三行 FETCH cur_printrecipe INTO rec_printrecipe; EXIT WHEN cur_printrecipe%NOTFOUND; dbms_output.put_line(rec_printrecipe.Amount ||''|| 它表示** rec_printrecipe **不能用于放置的左侧.. 它说两次“Statement ignored”.. 并且cur_printrecipe%NOTFOUND似乎也不工作.. – apoc

+0

@apoc - 你需要一个变量来选择,这是你的类型的一个实例,你不能直接使用类型。名字发生变化... –

1

错误消息表明您的存储过程无效,即由于代码中的错误而未成功编译。

  • 连接 SQL Developer的视图中,展开您的连接。
  • 展开该项目程序
  • 点击PROC_PRINTRECIPE
  • 在打开的视图,单击编译按钮。

然后,SQL Developer将显示您的过程中的错误位置。

+0

我无法在那里找到Compile按钮,但是我收到了错误消息,以及Alex Poole的select语句给了我。 – apoc