繁体   English   中英

Oracle 11g-运行PL / SQL游标

[英]Oracle 11g - Running PL/SQL Cursors

我试图在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

您能指出我出什么问题吗? 我似乎无法理解什么是错的

谢谢,布莱恩

有几个问题:

  • 您需要在游标定义之后(即在查询之后)使用分号。
  • 您不能同时使用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_recdate_destroyed类的book_cursor_rec ,而不是bookCursorRec (= bookcursorrec )和dateDestroyed (=已datedestroyed )。

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;

你需要改变

 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;

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

GRANT SELECT ON <table> TO <user> ;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM