我试图访问一个只用varchar2做索引的嵌套关联数组的第二层,但我遇到了一个问题。 我在网上找到的每个例子都在某个地方使用整数作为索引,这对我没有帮助。
下面是一些示例代码。
DECLARE
l_idx1 VARCHAR(50);
l_idx2 VARCHAR(50);
TYPE counter_type IS RECORD (
updated INTEGER,
inserted INTEGER,
deleted INTEGER
);
TYPE counter_tab IS TABLE OF counter_type INDEX BY VARCHAR2(50);
counters counter_tab;
BEGIN
counters('example_table1').updated := 0;
counters('example_table1').inserted := 0;
counters('example_table1').deleted := 0;
counters('example_table2').updated := 0;
counters('example_table2').inserted := 0;
counters('example_table2').deleted := 0;
counters('example_table3').updated := 0;
counters('example_table3').inserted := 0;
counters('example_table3').deleted := 0;
counters('example_table3').inserted := counters('example_table3').inserted + 12;
counters('example_table2').updated := counters('example_table2').updated + 32;
DBMS_OUTPUT.PUT_LINE('foo: ' || counters('example_table2').updated); -- testing this out
l_idx1 := counters.FIRST;
WHILE l_idx1 IS NOT NULL
LOOP
DBMS_OUTPUT.PUT_LINE('idx: ' || l_idx1);
l_idx2 := counters(l_idx1).FIRST; - This is where the problem is!!
WHILE l_idx2 IS NOT NULL
LOOP
DBMS_OUTPUT.PUT_LINE('Table: ' || l_idx1 || 'Counter: ' || counters(l_idx1).l_idx2);
IF counters(l_idx1).l_idx2 > 0
THEN
DBMS_OUTPUT.PUT_LINE('Records ' || l_idx2 || ' for table ' || l_idx1 || ': ' || counters(l_idx1).l_idx2);
END IF;
l_idx2 := counters(l_ldx1).NEXT(l_idx2); -- Like another problem!
END LOOP;
l_idx1 := counters.NEXT(l_idx1);
END LOOP;
END;
/
所以,我想做的是循环检查第一层的关联数组 对每一个数组都循环检查第二层数组并打印出数值 看起来好像很简单,而且可能是这样的。 :-)
谢谢你的帮助!
lkl
你只有一层数组(counter_tab
)类型的 counter_type
.
你可以通过循环 counters
但是计数器里面没有数组,所以这是不可能的。
用下面的代码,万一对你有帮助呢。
SQL> DECLARE
2 L_IDX1 VARCHAR(50);
3 L_IDX2 VARCHAR(50);
4 TYPE COUNTER_TYPE IS RECORD (
5 UPDATED INTEGER,
6 INSERTED INTEGER,
7 DELETED INTEGER
8 );
9 TYPE COUNTER_TAB IS
10 TABLE OF COUNTER_TYPE INDEX BY VARCHAR2(50);
11 COUNTERS COUNTER_TAB;
12 BEGIN
13 COUNTERS('example_table1').UPDATED := 0;
14 COUNTERS('example_table1').INSERTED := 0;
15 COUNTERS('example_table1').DELETED := 0;
16 COUNTERS('example_table2').UPDATED := 0;
17 COUNTERS('example_table2').INSERTED := 0;
18 COUNTERS('example_table2').DELETED := 0;
19 COUNTERS('example_table3').UPDATED := 0;
20 COUNTERS('example_table3').INSERTED := 0;
21 COUNTERS('example_table3').DELETED := 0;
22 COUNTERS('example_table3').INSERTED := COUNTERS('example_table3').INSERTED + 12;
23 COUNTERS('example_table2').UPDATED := COUNTERS('example_table2').UPDATED + 32;
24 DBMS_OUTPUT.PUT_LINE('foo: ' || COUNTERS('example_table2').UPDATED); -- testing this out
25 L_IDX1 := COUNTERS.FIRST;
26 WHILE L_IDX1 IS NOT NULL LOOP
27 DBMS_OUTPUT.PUT_LINE('idx: ' || L_IDX1);
28 DBMS_OUTPUT.PUT_LINE('updated: ' || COUNTERS(L_IDX1).UPDATED);
29 DBMS_OUTPUT.PUT_LINE('inserted: ' || COUNTERS(L_IDX1).INSERTED);
30 DBMS_OUTPUT.PUT_LINE('deleted: ' || COUNTERS(L_IDX1).DELETED);
31 L_IDX1 := COUNTERS.NEXT(L_IDX1);
32 END LOOP;
33
34 END;
35 /
foo: 32
idx: example_table1
updated: 0
inserted: 0
deleted: 0
idx: example_table2
updated: 32
inserted: 0
deleted: 0
idx: example_table3
updated: 0
inserted: 12
deleted: 0
PL/SQL procedure successfully completed.
SQL>
你可以做你要找的事,只是你如何去做,就会有很大的不同。首先让我们澄清一下你对什么需要索引(下标)和如何引用Record的误解。当你定义一个类型的Record时,你并不是通过索引来访问它,(正如其他人所指出的)你可以 只按名称访问记录属性. 以这种方式,记录的引用和表的引用是一样的,当引用一个表的列时,你使用的语法是TABLE_NAME.COLUMN_NAME,同样的,记录的属性引用是RECORD_NAME.ATTRIBUTE_NAME。当引用一个表列时,你使用语法TABLE_NAME.COLUMN_NAME同样引用一个记录属性为RECORD_NAME.ATTRIBUTE_NAME。 唯一被索引引用的plsql对象是一个集合(嵌套表、关联数组、varray)。所以要想得到你想要的东西,你需要声明一个 荟萃 而不是一个记录的集合。在这种情况下,一个整数的关联数组的关联数组。进一步的索引方式,每个索引都用括号括起来,与其他(s)分开,所以C(i1)(i2)而不是C(i1,i2)。你还必须记住你要引用的是什么级别,因为集合属性(first, last, next, ...)等都是独立的索引(算是吧)。但是如果你能把所有的事情都弄清楚,那么级别的数量是没有限制的(AFAIK)。 下面展示了如何去做你想要的事情。它值得努力吗?在这种情况下,可能不值得,除非你的全部问题需要在事先不知道索引值的情况下引用(在这种情况下,你需要防范NO_DATA_FOUND异常),或者你需要在飞行中添加索引值。只有你能决定。
declare
l_idx1 varchar(50); -- 1st level index
l_idx2 varchar(8); -- 2nd level index
-- 2nd level collection. Defines a collection of integers
type counter_type is
table of integer
index by varchar2(8) ;
-- 1st level collection. Defines a collection of a collection of integers
type counter_tab is
table of counter_type
index by varchar2(50);
-- variable for collection of a collection of integers
counters counter_tab;
begin
-- initialize counters
counters('example_table1')('updated') := 0;
counters('example_table1')('inserted') := 0;
counters('example_table1')('deleted') := 0;
counters('example_table2')('updated') := 0;
counters('example_table2')('inserted') := 0;
counters('example_table2')('deleted') := 0;
counters('example_table3')('updated') := 0;
counters('example_table3')('inserted') := 0;
counters('example_table3')('deleted') := 0;
-- perform some operations
counters('example_table3')('inserted') := counters('example_table3')('inserted') + 12;
counters('example_table2')('updated') := counters('example_table2')('updated') + 32;
-- loop through results
l_idx1 := counters.first;
while l_idx1 is not null
loop
dbms_output.put_line('Outer index: ' || l_idx1);
l_idx2 := counters(l_idx1).first ;
while l_idx2 is not null
loop
dbms_output.put_line(' ''' || l_idx2 || ':'' ' || to_char(counters(l_idx1)(l_idx2)));
l_idx2 := counters(l_idx1).next(l_idx2);
end loop;
l_idx1 := counters.next(l_idx1);
end loop;
end;