return 来自用户 table 记录的所有值
return all values from user table record
比方说,我有一个名为 get_prod 的过程,它 returns 一个用户定义的记录:
create or replace package test is
cursor cGetProducts(NROWS integer) is
select prod.PROD_REF,
prod.PROD_IDENT,
prod.PROD_DESCR,
prod.PROD_GENDATE,
prod.PROD_GENUSERNO,
pu.PU_LENGTH,
pu.PU_WIDTH,
pu.PU_HEIGHT,
pu.PU_WEIGHT
from product prod,
product_um pu
where prod.PROD_REF = pu.PROD_REF
and prod.PROD_UMBASE = pu.PU_UM
and rownum <= NROWS;
type rec_tt is record(
prod_ref integer,
prod_ident varchar(50),
PROD_DESCR varchar(100),
prod_gendate date,
prod_genuser integer,
prod_length number(21,6),
prod_width number(21,6),
prod_height number(21,6),
prod_weight number(21,6)
);
type prod_t is table of rec_tt index by BINARY_INTEGER;
procedure get_prod(
MAXROWS in integer,
NROWS in integer,
o_table out prod_t
);
end test;
/
create or replace package body test is
procedure get_prod(
MAXROWS in integer,
NROWS in integer,
o_table out prod_t
)is
begin
if not cGetProducts%isOpen then
open cGetProducts(NROWS);
end if;
fetch cGetProducts
bulk collect into o_table;
if cGetProducts%NotFound or MAXROWS>0 and cGetProducts%RowCount>MAXROWS then
close cGetProducts;
end if;
end get_prod;
end test;
/
测试这个程序没什么大不了的,但要查看 table 的结果,我不得不遍历 table 并记下记录中的每个参数,例如那:
declare
-- Non-scalar parameters require additional processing
o_table TEST.PROD_T;
begin
-- Call the procedure
test.get_prod(
MAXROWS => 0,
NROWS => 99,
o_table => o_table);
for i in 1..o_table.count loop
dbms_output.put_line(o_table(i).prod_ref);
dbms_output.put_line(o_table(i).prod_ident);
...
...
end loop;
end;
但我会记下记录的每个参数并获取它。有没有更简单的方法来做到这一点,尤其是当记录的参数更多时?
您可以使用数据库定义的自定义类型。这些类型可以有自己的方法,所以你可以只实现一个输出方法。
下面是我的意思的例子:
create or replace type VarcharArray_T as
table of varchar2(32767 char);
create or replace type VarcharArrayObj_T force as object
(
-- Attributes
Value VarcharArray_T,
-- Constructor
constructor function VarcharArrayObj_T return self as result,
-- Methods
member procedure Output
)
create or replace type body VarcharArrayObj_T is
--
-- Constructor
--
constructor function VarcharArrayObj_T
return self as result
is
begin
self.Value := VarchArarray_T();
return;
end;
--
-- Prints the values to console
--
member procedure Output
is
i number := 0;
begin
i := self.Value.First();
while i is not null
loop
-- !!! You can implement the child attribute access here once !!!
DBMS_Output.Put_Line(self.Value(i));
i := self.Value.Next(i);
end loop;
end;
end;
比方说,我有一个名为 get_prod 的过程,它 returns 一个用户定义的记录:
create or replace package test is
cursor cGetProducts(NROWS integer) is
select prod.PROD_REF,
prod.PROD_IDENT,
prod.PROD_DESCR,
prod.PROD_GENDATE,
prod.PROD_GENUSERNO,
pu.PU_LENGTH,
pu.PU_WIDTH,
pu.PU_HEIGHT,
pu.PU_WEIGHT
from product prod,
product_um pu
where prod.PROD_REF = pu.PROD_REF
and prod.PROD_UMBASE = pu.PU_UM
and rownum <= NROWS;
type rec_tt is record(
prod_ref integer,
prod_ident varchar(50),
PROD_DESCR varchar(100),
prod_gendate date,
prod_genuser integer,
prod_length number(21,6),
prod_width number(21,6),
prod_height number(21,6),
prod_weight number(21,6)
);
type prod_t is table of rec_tt index by BINARY_INTEGER;
procedure get_prod(
MAXROWS in integer,
NROWS in integer,
o_table out prod_t
);
end test;
/
create or replace package body test is
procedure get_prod(
MAXROWS in integer,
NROWS in integer,
o_table out prod_t
)is
begin
if not cGetProducts%isOpen then
open cGetProducts(NROWS);
end if;
fetch cGetProducts
bulk collect into o_table;
if cGetProducts%NotFound or MAXROWS>0 and cGetProducts%RowCount>MAXROWS then
close cGetProducts;
end if;
end get_prod;
end test;
/
测试这个程序没什么大不了的,但要查看 table 的结果,我不得不遍历 table 并记下记录中的每个参数,例如那:
declare
-- Non-scalar parameters require additional processing
o_table TEST.PROD_T;
begin
-- Call the procedure
test.get_prod(
MAXROWS => 0,
NROWS => 99,
o_table => o_table);
for i in 1..o_table.count loop
dbms_output.put_line(o_table(i).prod_ref);
dbms_output.put_line(o_table(i).prod_ident);
...
...
end loop;
end;
但我会记下记录的每个参数并获取它。有没有更简单的方法来做到这一点,尤其是当记录的参数更多时?
您可以使用数据库定义的自定义类型。这些类型可以有自己的方法,所以你可以只实现一个输出方法。
下面是我的意思的例子:
create or replace type VarcharArray_T as table of varchar2(32767 char); create or replace type VarcharArrayObj_T force as object ( -- Attributes Value VarcharArray_T, -- Constructor constructor function VarcharArrayObj_T return self as result, -- Methods member procedure Output ) create or replace type body VarcharArrayObj_T is -- -- Constructor -- constructor function VarcharArrayObj_T return self as result is begin self.Value := VarchArarray_T(); return; end; -- -- Prints the values to console -- member procedure Output is i number := 0; begin i := self.Value.First(); while i is not null loop -- !!! You can implement the child attribute access here once !!! DBMS_Output.Put_Line(self.Value(i)); i := self.Value.Next(i); end loop; end; end;