我不知道它是否是正确的术语,但我将“在内存表中”称为这样创建的对象:
create type InMemReg is object (field1 varchar2(10), field2 varchar2(20), field3 number);
create type InMemTab is table of InMemReg;
在这种情况下,我的“内存表”是“InMemTab”。我的问题是,当我以前不知道元素的数量时,我如何填充这种对象?我在某些地方看到过这种类型的初始化:
declare
v_uno InMemReg := InMemReg('a','b',1999);
v_dos InMemReg := InMemReg('A','Z',2000);
t_tres InMemTab := InMemTab();
begin
t_tres := InMemTab(v_uno, v_dos);
在这种情况下,我在初始化“t_tres”之前有明确的2个对象,但在动态场景中,我可能有n个元素,我不知道如何填充它。
在另一种OO语言中可能是这样的:
t_tres.add(OtherObject)
答案 0 :(得分:10)
类型InMemTab
是Oracle用语中的嵌套表。
等同于add
方法的方法是调用extend
方法,然后将OtherObject
分配给嵌套表中的最后一个位置。
SQL> ed
Wrote file afiedt.buf
1 declare
2 v_uno InMemReg := InMemReg('a','b',1999);
3 v_dos InMemReg := InMemReg('A','Z',2000);
4 t_tres InMemTab := InMemTab();
5 begin
6 t_tres.extend;
7 t_tres( t_tres.count ) := v_uno;
8 t_tres.extend;
9 t_tres( t_tres.count ) := v_dos;
10 dbms_output.put_line( 't_tres has ' || t_tres.count || ' elements.' );
11* end;
12 /
t_tres has 2 elements.
PL/SQL procedure successfully completed.
您可以将其分解为add
程序
SQL> ed
Wrote file afiedt.buf
1 declare
2 v_uno InMemReg := InMemReg('a','b',1999);
3 v_dos InMemReg := InMemReg('A','Z',2000);
4 t_tres InMemTab := InMemTab();
5 procedure add( p_nt IN OUT InMemTab,
6 p_elem IN InMemReg )
7 as
8 begin
9 p_nt.extend;
10 p_nt( p_nt.count ) := p_elem;
11 end;
12 begin
13 add( t_tres, v_uno );
14 add( t_tres, v_dos );
15 dbms_output.put_line( 't_tres has ' || t_tres.count || ' elements.' );
16* end;
17 /
t_tres has 2 elements.
PL/SQL procedure successfully completed.
答案 1 :(得分:7)
通常从数据本身填充集合,这意味着您没有显式添加字符串和数字集,而是从其他表中提取数据。因为这是与集合相关的常见和自然的事情,所以Oracle通过pl / sql中的“BULK COLLECT INTO”子句轻松实现。例如:
DECLARE
TYPE EmployeeSet IS TABLE OF employees%ROWTYPE;
underpaid EmployeeSet;
-- Holds set of rows from EMPLOYEES table.
CURSOR c1 IS SELECT first_name, last_name FROM employees;
TYPE NameSet IS TABLE OF c1%ROWTYPE;
some_names NameSet;
-- Holds set of partial rows from EMPLOYEES table.
BEGIN
-- With one query,
-- bring all relevant data into collection of records.
SELECT * BULK COLLECT INTO underpaid FROM employees
WHERE salary < 5000 ORDER BY salary DESC;
-- Process data by examining collection or passing it to
-- eparate procedure, instead of writing loop to FETCH each row.
DBMS_OUTPUT.PUT_LINE
(underpaid.COUNT || ' people make less than 5000.');
FOR i IN underpaid.FIRST .. underpaid.LAST
LOOP
DBMS_OUTPUT.PUT_LINE
(underpaid(i).last_name || ' makes ' || underpaid(i).salary);
END LOOP;
-- You can also bring in just some of the table columns.
-- Here you get the first and last names of 10 arbitrary employees.
SELECT first_name, last_name
BULK COLLECT INTO some_names
FROM employees
WHERE ROWNUM < 11;
FOR i IN some_names.FIRST .. some_names.LAST
LOOP
DBMS_OUTPUT.PUT_LINE
('Employee = ' || some_names(i).first_name
|| ' ' || some_names(i).last_name);
END LOOP;
END;
/
您通常不需要担心扩展或您将拥有多少元素,您通常可以将其插入,然后根据需要使用集合的内置功能(计数,循环,比较不同的集合) ,设置操作等)