记录变量

记录类型类似于行类型。记录类型的相关介绍详见 记录类型

记录类型从SELECT或者FOR命令中获取实际的行结构。一个记录变量的内部字段结构可以在每次赋值的时候修改。因此,只有当记录变量被赋值后才能通过recordvar.field_name来访问内部字段。

值得注意的是,函数参数不能是记录类型。且函数返回值也不能是记录类型。例如以下语句是错误的:

SELECT field_name FROM func_ret_record(); --错误
SELECT (func_ret_record()).field_name; --错误

因为外部调用函数的SQL语句对记录的内部字段结构不可见。 在包中,函数可以返回一个记录类型,并在别的过程中使用其返回值, sql中不可以直接调用返回值为记录类型的函数。

示例1:记录变量的错误使用

--  清理环境
DROP PROCEDURE proc;
DROP PACKAGE pack;

--创建包
create or replace package pack is
    type rec is 
        record 
        (
            a int, 
            b int
        );
    function f return rec;
end;
/

create or replace package body pack is
    function f return rec is        
        a rec; --记录变量的声明语法
    begin
        a.a := 1;
        a.b := 2;
        return a;
    end;
end;
/

--清理环境
DROP PROCEDURE proc;

CREATE OR REPLACE PROCEDURE proc AS
declare
    a pack.rec;
begin
    a := pack.f;
    dbms_output.put_line(a.a);
    dbms_output.put_line(a.b);
end;

/

EXEC proc;
1
2
--函数参数不能是记录类型,且函数返回值也不能是记录类型
select a from pack.f;
ERROR, 模式 "PACK" 不存在或无权访问

select pack.f.a;
ERROR, Adding missing FROM-clause entry for table "F" 不再支持


--  删除
DROP PROCEDURE proc;
DROP PACKAGE pack;

示例2:记录变量的正确使用

DROP PROCEDURE test CASCADE;
DROP TABLE tb1 CASCADE;

create table tb1
(
    id int,
    flag char(128)
);
insert into tb1 values(1000,'cur_one');
insert into tb1 values(2000,'cur_two');
insert into tb1 values(3000,'cur_three');
insert into tb1 values(4000,'cur_four');

create or replace procedure test() as
declare
    type r1 is 
        record
        (
            id int,
            flag char(128)
        );
    cursor c1 is select * from tb1;
    id int;
    item r1;
begin
    for item in c1 loop
        id := item.id;
        dbms_output.put_line(item.id);
        dbms_output.put_line(item.flag);
    end loop;
end;

/

exec test();
1000
cur_one                                                                                                                         
2000
cur_two                                                                                                                         
3000
cur_three                                                                                                                       
4000
cur_four                                                                                                                        


--  删除
DROP PROCEDURE test CASCADE;
DROP TABLE tb1 CASCADE;