【问题标题】:Oracle 11g - Running PL/SQL CursorsOracle 11g - 运行 PL/SQL 游标
【发布时间】:2012-02-07 07:51:29
【问题描述】:

我正在尝试在 Oracle 11g 上运行此代码,但它给了我以下错误。我好像没弄好。

DECLARE
    CURSOR bookcursor IS
    SELECT btName, BookCopy.Isbn, pubName, dateDestroyed
      FROM booktitle bt
      JOIN publisher p
        ON bt.pubId = p.pubId 
      JOIN bookcopy bc
        ON bt.Isbn = bc.Isbn 
     WHERE datedestroyed IS NULL
    ;
    bookcursorrec bookcursor%ROWTYPE;
BEGIN
    OPEN bookcursor;
    LOOP
        FETCH bookcursor INTO bookcursorrer;
        EXIT WHEN bookcursor%NOTFOUND;
        dbms_output.put_line( 'ISBN: ' ||bookcursorrec.isbn
                              || ' - Book Name: ' || bookcursorrec.btname
                              || ' - Publisher: ' || bookcursorrec.pubname );
    END LOOP;
    CLOSE bookcursor;
END;


ERROR at line 3:
ORA-06550: line 3, column 20:
PL/SQL: ORA-00904: "BOOKCOPY"."ISBN": invalid identifier
ORA-06550: line 3, column 5:
PL/SQL: SQL Statement ignored
ORA-06550: line 2, column 12:
PLS-00341: declaration of cursor 'BOOKCURSOR' is incomplete or malformed
ORA-06550: line 11, column 19:
PL/SQL: Item ignored
ORA-06550: line 15, column 31:
PLS-00201: identifier 'BOOKCURSORRER' must be declared
ORA-06550: line 15, column 9:
PL/SQL: SQL Statement ignored
ORA-06550: line 17, column 42:
PLS-00320: the declaration of the type of this expression is incomplete or
malformed
ORA-06550: line 17, column 9:
PL/SQL: Statement ignored

你能指出我出了什么问题吗?我似乎无法理解哪里出了问题

谢谢, 布赖恩

【问题讨论】:

    标签: sql oracle plsql cursor oracle11g


    【解决方案1】:

    检查用户是否已选择授予相关对象或表也很重要。 通过授予用户对游标中使用的表的选择访问权限,我的问题得到了解决;

    GRANT SELECT ON <table> TO <user> ;
    

    【讨论】:

      【解决方案2】:
      Set Serveroutput on
      CREATE OR REPLACE A PROCEDURE TO GET_SENRYO_EMP
      DECLARE
          CURSOR Senryocursor IS
          SELECT first_name, last_name, full_Name,Gender,DOB,Martialstatus,Nationality,Telephone,Email_id,job,Nationalidentifier,Hire_date
            FROM Senryo;
      --Senryocursorrec senryocursor%rowtype;
      BEGIN
       OPEN Senryocursor;
      LOOP
              FETCH Senryocursor INTO Senryocursorrec;
              EXIT WHEN Senryocursor%NOTFOUND;
              dbms_output.put_line( 'Senryocursor ' ||Senryocursorrec
                                    || '- Full_name :' || Senryocursorrec.full_name
                                    || ' - Job: ' || Senryocursorrec.Job );
          END LOOP;
          CLOSE Senryocursor;
      END;
      

      【讨论】:

        【解决方案3】:

        有几个问题:

        • 游标定义后(即查询后)需要一个分号。
        • 您不能同时使用bookCursor 作为游标的名称和您获取的记录的名称。 (我注意到你的一些代码使用了bookCursorRec 来表示后者,所以我会使用它。)
        • fetch 需要获取到的东西,也就是到bookCursorRec。
        • 您需要在调用dbms_output.put_line 后使用分号。
        • 您的查询似乎有误;看起来两个连接都是交叉连接。

        把它放在一起,稍微调整一下格式和结构,让它更“惯用”PL/SQL:

        DECLARE
            CURSOR bookcursor IS
            SELECT btname, isbn, pubname, datedestroyed
              FROM booktitle bt
              JOIN publisher p
                ON bt.pid = p.id -- this is just a guess
              JOIN bookcopy bc
                ON bt.bcid = bc.id -- this is just a guess
             WHERE datedestroyed IS NULL
            ;
            bookcursorrec bookcursor%ROWTYPE;
        BEGIN
            OPEN bookcursor;
            LOOP
                FETCH bookcursor INTO bookcursorrec;
                EXIT WHEN bookcursor%NOTFOUND;
                dbms_output.put_line( 'ISBN: ' ||bookcursorrec.isbn
                                      || ' - Book Name: ' || bookcursorrec.btname
                                      || ' - Publisher: ' || bookcursorrec.pubname );
            END LOOP;
            CLOSE bookcursor;
        END;
        /
        

        顺便说一下,Oracle 标识符大多是区分大小写的(因为它们被隐式转换为大写,除非你用双引号括起来),所以人们通常会使用像 book_cursor_rec 和 date_destroyed 这样的标识符,而不是bookCursorRec (= bookcursorrec) 和 dateDestroyed (= datedestroyed)。

        【讨论】:

        • ruakh 我收到此错误:第 14 行错误:ORA-06550:第 14 行,第 9 列:PLS-00103:在预期以下情况之一时遇到符号“FETCH”::=。 ( % ; 符号 ";" 被替换为 "FETCH" 以继续。
        • @Brian:哦,哎呀,你的dbms_output.put_line(...) 语句后面也少了一个分号。我会用这个更新我的答案,以及我看到的其他一些问题。 . .
        • 嗨,我用一个新错误更新了我的主要答案中的代码。我似乎无法做到这一点:/
        • @Brian:第一个错误(“列模糊定义”)是因为您在 booktitle 和 bookcopy 中都有一个 isbn,所以 Oracle 无法判断您指的是哪个。 (从技术上讲,由于加入,它们是等效的,但 Oracle 不承认这一点。)因此,您需要将 SELECT 子句中的 isbn 更改为 booktitle.isbn 或 bookcopy.isbn(根据您的喜好) .我相信第二个错误(“游标 'BOOKCURSOR' 的声明不完整或格式错误”)是第一个错误的结果:一旦你修复了查询,那应该会消失。
        • @Brian:第三个错误(“必须声明标识符 'BOOKCURSORRE'”)是因为我的答案中有一个错字(写 bookcursorre 而不是 bookcursorrrec),你复制了- 并在错误的时间粘贴。很抱歉!
        【解决方案4】:

        你需要改变

         fetch  bookCursor
        

        进入

         fetch bookCursor into bookCursorRec;
        

        在while上方。

        还有

        cursor bookCursor is
               SELECT btName, ISBN, pubName, dateDestroyed
               FROM BookTitle bt, publisher p, BookCopy bc
               WHERE bt.bcId = bcId
               AND dateDestroyed is null
               bookCursor bookCursor%rowtype;
        

        应该阅读

        cursor bookCursor is
               SELECT btName, ISBN, pubName, dateDestroyed
               FROM BookTitle bt, publisher p, BookCopy bc
               WHERE bt.bcId = bcId
               AND dateDestroyed is null;
        
               bookCursorRec bookCursor%rowtype;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-07-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-01
          • 1970-01-01
          相关资源
          最近更新 更多