Oracle 是否可以在游标内调用记录类型?

Oracle 是否可以在游标内调用记录类型?,oracle,plsql,Oracle,Plsql,我试图在游标内调用一个记录类型,尽管它没有给我语法错误,但它仍然无法编译。我的任务是创建一个游标,该游标允许检索数据并将捐赠者类型和认捐金额的多个组合作为收款输入进行处理。输出结果应为符合捐赠者类型且大于所示质押金额的每个质押的捐赠者名称和质押金额。以下是表格: 供体 Name Null? Type --------- -------- ------------ IDDONOR NOT NULL NUMBER(4) FIRSTNAME

我试图在游标内调用一个记录类型,尽管它没有给我语法错误,但它仍然无法编译。我的任务是创建一个游标,该游标允许检索数据并将捐赠者类型和认捐金额的多个组合作为收款输入进行处理。输出结果应为符合捐赠者类型且大于所示质押金额的每个质押的捐赠者名称和质押金额。以下是表格:

供体

Name      Null?    Type         
--------- -------- ------------ 
IDDONOR   NOT NULL NUMBER(4)    
FIRSTNAME          VARCHAR2(15) 
LASTNAME           VARCHAR2(30) 
TYPECODE           CHAR(1)      
STREET             VARCHAR2(40) 
CITY               VARCHAR2(20) 
STATE              CHAR(2)      
ZIP                VARCHAR2(9)  
PHONE              VARCHAR2(10) 
FAX                VARCHAR2(10) 
EMAIL              VARCHAR2(25) 
NEWS               CHAR(1)      
DTENTERED          DATE     
DDU承诺

Name        Null?    Type        
----------- -------- ----------- 
IDPLEDGE    NOT NULL NUMBER(5)   
IDDONOR              NUMBER(4)   
PLEDGEDATE           DATE        
PLEDGEAMT            NUMBER(8,2) 
IDPROJ               NUMBER(5)   
IDSTATUS             NUMBER(2)   
WRITEOFF             NUMBER(8,2) 
PAYMONTHS            NUMBER(3)   
CAMPAIGN             NUMBER(4)   
FIRSTPLEDGE          CHAR(1)     
我的代码:

DECLARE
   CURSOR donnor_pledge (dtype_amount RECORD) IS
     SELECT d.FIRSTNAME, d.LASTNAME, p.PLEDGEAMT
       FROM DD_DONOR d INNER JOIN DD_PLEDGE p
         USING (IDDONOR)
       WHERE d.TYPECODE = dtype_amount.type AND 
       p.PLEDGEAMT > dtype_amount.amount;
       
   TYPE dtype_amount IS RECORD (
     type DD_DONOR.TYPECODE%TYPE := 'I',
     amount DD_PLEDGE.PLEDGEAMT%TYPE) := 250);
     
BEGIN
   OPEN donnor_pledge;
   DBMS_OUTPUT.PUT_LINE('Donor name: ' || d.FIRSTNAME || ' ' || d.LASTNAME);
   DBMS_OUTPUT.PUT_LINE('Pledge amount: ' || p.PLEDGEAMT);
   CLOSE donnor_pledge;    
END;
错误消息:

Error report -
ORA-06550: line 2, column 39:
PLS-00201: identifier 'RECORD' must be declared
ORA-06550: line 2, column 4:
PL/SQL: Item ignored
ORA-06550: line 14, column 9:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 14, column 4:
PL/SQL: SQL Statement ignored
ORA-06550: line 15, column 45:
PLS-00201: identifier 'D.FIRSTNAME' must be declared
ORA-06550: line 15, column 4:
PL/SQL: Statement ignored
ORA-06550: line 16, column 50:
PLS-00225: subprogram or cursor 'P' reference is out of scope
ORA-06550: line 16, column 4:
PL/SQL: Statement ignored
ORA-06550: line 17, column 10:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 17, column 4:
PL/SQL: SQL Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.

您需要先声明记录类型,然后再在游标中使用它,然后声明一个变量,让记录传递到游标中,然后在游标中循环

声明
类型dtype\u金额为记录(
类型代码DD_捐赠者。类型代码%TYPE,
金额DD\U质押。质押百分比类型
);
抵押物(p_类型金额D类型金额)为
选择d.FIRSTNAME,
d、 姓,
p、 抵押小组
来自DD_捐赠者d
内连接DD\p
使用(IDR)
其中d.TYPECODE=p_typeamount.TYPECODE
p.marqueeamt>p_typeamount.amount;
p_类型金额D类型金额;
p\u名称\u金额或\u质押%ROWTYPE;
开始
p_typeamount.typecode:=“I”;
p_类型金额:金额=250;
未结抵押(p_类型金额);
环
将donnor_质押物提取到p_名称_金额中;
未找到%1或%2时退出;
DBMS|u OUTPUT.PUT|u LINE('捐赠者名称:'||p|u name|u amount.FIRSTNAME |'| p|u name|u amount.LASTNAME);
DBMS_OUTPUT.PUT_LINE('质押金额:'| | p_name_amount.质押);
端环;
关闭donnor_承诺;
结束;
/
或者,您可以使用光标的两个参数在没有记录的情况下执行此操作:

声明
光标donnor_质押(p_类型代码字符,p_金额编号)为
选择d.FIRSTNAME,
d、 姓,
p、 抵押小组
来自DD_捐赠者d
内连接DD\p
使用(IDR)
其中d.TYPECODE=p_TYPECODE
p.marqueeamt>p_金额;
p\u名称\u金额或\u质押%ROWTYPE;
开始
开放式抵押(“I”,250);
环
将donnor_质押物提取到p_名称_金额中;
未找到%1或%2时退出;
DBMS|u OUTPUT.PUT|u LINE('捐赠者名称:'||p|u name|u amount.FIRSTNAME |'| p|u name|u amount.LASTNAME);
DBMS_OUTPUT.PUT_LINE('质押金额:'| | p_name_amount.质押);
端环;
关闭donnor_承诺;
结束;
/

dbfiddle

我更喜欢第二种解决方案。它看起来不仅更干净,而且更符合逻辑。
dtype\u amount\u rec\u 1
的字段从未初始化,因此将为
NULL
,并且光标将不会有任何行。此外,您已将
250
I
硬编码到光标中,而不是从表中返回质押金额,因此即使光标返回行,也会返回错误的质押金额。
    DECLARE
   TYPE dtype_amount IS RECORD(
     firstname DD_DONOR.FIRSTNAME%TYPE,
     lastname DD_DONOR.LASTNAME%TYPE,
     PLEDGEAMT DD_PLEDGE.PLEDGEAMT%TYPE,    
     atype DD_DONOR.TYPECODE%TYPE  
     
     );
   CURSOR donnor_pledge (adtype_amount dtype_amount ) IS
     SELECT d.FIRSTNAME, d.LASTNAME, 250, 'I' 
       FROM DD_DONOR d INNER JOIN DD_PLEDGE p
         USING (IDDONOR)
       WHERE d.TYPECODE = adtype_amount.atype AND 
       p.PLEDGEAMT > adtype_amount.PLEDGEAMT;    
       
     dtype_amount_rec_1  dtype_amount;   
     dtype_amount_rec_2  dtype_amount;    
             
BEGIN
   null;

   OPEN donnor_pledge(dtype_amount_rec_1);
      FETCH donnor_pledge INTO dtype_amount_rec_2 ;
      DBMS_OUTPUT.PUT_LINE('Donor name: ' || dtype_amount_rec_2.FIRSTNAME || ' ' || dtype_amount_rec_2.LASTNAME);
      DBMS_OUTPUT.PUT_LINE('Pledge amount: ' || dtype_amount_rec_2.PLEDGEAMT);            
   CLOSE donnor_pledge;   

END;
/
show errors