我对pl / sql比较新,我试图用记录对象创建一个列表,但我不知道如何为记录项中的两个字段初始化列表的每个项目。例如:在程序"新项目"我怎么能初始化例子(1)? with example(1).id_std:= integer和example(1).procent:= integer?谢谢!
这就是我的代码的样子:
set serveroutput on;
CREATE OR REPLACE PACKAGE newExercise IS
TYPE item IS RECORD(
id_std INTEGER,
procent INTEGER
);
TYPE tabel IS VARRAY(5) OF item;
PROCEDURE newItem (example tabel);
example2 tabel := tabel();
end newExercise;
/
CREATE OR REPLACE PACKAGE BODY newExercise IS
PROCEDURE newItem (example tabel) IS
BEGIN
FOR i IN 1..example.LIMIT LOOP
DBMS_OUTPUT.PUT_LINE(example(i));
end loop;
end newItem;
end newExercise;
/
答案 0 :(得分:3)
记录类型用于存储查询结果。所以你可以这样做:
declare
recs newExercise.tabel;
begin
select level, level * 0.25
bulk collect into recs
from dual
connect by level <= 5;
newExercise.newItem (recs);
end;
/
请注意,VARRAY不是用于此目的的合适集合类型,因为并不总是可以预测查询将返回多少行。最好使用
TYPE tabel IS table OF item;
答案 1 :(得分:0)
当您参考记录时,您通常必须指定特定字段。这将使用计算值填充记录;为了能够做到这一点,我必须在规范中将过程参数从默认的IN
方向更改为IN OUT
:
CREATE OR REPLACE PACKAGE newExercise IS
TYPE item IS RECORD(
id_std INTEGER,
procent INTEGER
);
TYPE tabel IS VARRAY(5) OF item;
PROCEDURE newItem (example IN OUT tabel);
-- ^^^^^^ make in/out to be updateable
-- example2 tabel := tabel(); -- not used
END newExercise;
/
并在身体中:
CREATE OR REPLACE PACKAGE BODY newExercise IS
PROCEDURE newItem (example IN OUT tabel) IS
-- ^^^^^^ make in/out to be updateable
BEGIN
FOR i IN 1..example.LIMIT LOOP
-- extend collection to create new record
example.extend();
-- assign values to record fields
example(i).id_std := i;
example(i).procent := 100 * (1/i);
END LOOP;
END newItem;
END newExercise;
/
定义中LIMIT
为5,但varray实例最初为空(来自tabel()
)。对于填充,您可以从1循环到5的限制,但是您必须extend()
集合才能在该位置实际创建记录。默认情况下,创建记录时将所有字段设置为null。然后,您可以将值分配给每个记录的字段。 (显然我已经做了一些事情)。
然后,您可以使用匿名块进行测试:
declare
example newExercise.tabel := newExercise.tabel();
begin
-- call procedure
newExercise.newItem(example);
-- display contents for debuggibg
FOR i IN 1..example.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('Item ' || i
|| ' id_std: ' || example(i).id_std
-- ^^^^^^^ refer to field
|| ' procent: ' || example(i).procent);
-- ^^^^^^^ refer to field
END LOOP;
end;
/
Item 1 id_std: 1 procent: 100
Item 2 id_std: 2 procent: 50
Item 3 id_std: 3 procent: 33
Item 4 id_std: 4 procent: 25
Item 5 id_std: 5 procent: 20
PL/SQL procedure successfully completed.
我已将原始循环显示在该块中的数组内容中,因为您通常不会将其作为过程的一部分。您仍然可以使用LIMIT
作为该循环,但如果程序没有完全填充它,则COUNT
会更安全。
你也可以在循环之前延长一次:
PROCEDURE newItem (example IN OUT tabel) IS
BEGIN
-- extend collection to create all new records
example.extend(example.LIMIT);
FOR i IN 1..example.LIMIT LOOP
example(i).id_std := i;
example(i).procent := 100 * (1/i);
END LOOP;
END newItem;
如果您已经知道要分配的值 - 并且它们不是来自表格,在这种情况下您使用APC的方法 - 您可以只分配到最后创建的记录;这是一个相当人为的例子:
PROCEDURE newItem (example IN OUT tabel) IS
BEGIN
example.extend(); -- first record
example(example.LAST).id_std := 1;
example(example.LAST).procent := 7;
example.extend(); -- second record, left with null fields
example.extend(); -- third record
example(example.LAST).id_std := 3;
example(example.LAST).procent := 21;
example.extend(); -- fourth record, left with null fields
END newItem;
和同一个匿名块现在给出:
Item 1 id_std: 1 procent: 7
Item 2 id_std: procent:
Item 3 id_std: 3 procent: 21
Item 4 id_std: procent:
PL/SQL procedure successfully completed.
注意空值,并且没有第5行。
或者再次扩展集合一次,并直接参考编号记录:
PROCEDURE newItem (example IN OUT tabel) IS
BEGIN
example.extend(4);
example(1).id_std := 1;
example(1).procent := 7;
example(3).id_std := 3;
example(3).procent := 21;
END newItem;
从匿名块获得相同的结果。