как "пожать" pls-sql таблицу

nxx
Дата: 12.11.2008 14:19:40
declare

type test_r is record(x1 number);

type test_t is table of test_r index by binary_integer;

xxtest test_t;

begin

for i in 1..10 loop
  xxtest(i).x1 := i;
end loop;

xxtest.delete(5); -- удаляем произвольные элементы

for i in 1..xxtest.count loop
 dbms_output.put_line(xxtest(i).x1);
end loop;

end;

результат - NO_DATA_FOUND

видимо, удаление оставяет "дыры"
как сделать (желательно красиво) чтобы дыр не было ?
\\guest//
Дата: 12.11.2008 14:22:01
if xxtest.exists(i) then...
Denis Popov
Дата: 12.11.2008 14:27:21

nxx wrote:

> видимо, удаление оставяет "дыры"
> как сделать (желательно красиво) чтобы дыр не было ?

Обходи элементы по-другому:

declare
   type test_r is record(x1 number);
   type test_t is table of test_r index by binary_integer;
   xxtest test_t;
   i pls_integer;
begin
   for i in 1..10 loop
     xxtest(i).x1 := i;
   end loop;

   xxtest.delete(5); -- удаляем произвольные элементы
   dbms_output.put_line(xxtest.count);

   i := xxtest.first;
   if i is not null then
     loop
       dbms_output.put_line(xxtest(i).x1);
       i := xxtest.next(i);
       exit when i is null;
     end loop;
   end if;

--  for i in 1..xxtest.count loop
--   dbms_output.put_line(xxtest(i).x1);
--  end loop;
end;
/

Posted via ActualForum NNTP Server 1.4

nxx
Дата: 12.11.2008 14:27:32
\\guest//
if xxtest.exists(i) then...


боюсь, что не подойдет
потому как
в общем случае
задача такая

получаю таблицу входным параметром
фильтрую её
возвращаю выходным параметром

далее она будет передана другой процедуре на вход
та процедура не моя и менять её нельзя
Elic
Дата: 12.11.2008 14:30:51
nxx
type test_t is table of test_r index by binary_integer;
видимо, удаление оставяет "дыры"
Ты просто не понимаешь, что такое ассоциативный массив.
nxx
как сделать (желательно красиво) чтобы дыр не было ?
RTFM Looping Through Collection Elements (FAQ)
orawish
Дата: 12.11.2008 14:31:40
nxx
..как сделать (желательно красиво) чтобы дыр не было ?

пиэльэскуэльные таблицы суть то же что (в других языках) ассоциативные массивы.
Т.е. понятие дыры (в индексе) для них чужеродная абстракция.
Есть API (а именно - first/last/next/prior) - где никаких проблем
nxx
Дата: 12.11.2008 14:40:22
orawish
nxx
..как сделать (желательно красиво) чтобы дыр не было ?

пиэльэскуэльные таблицы суть то же что (в других языках) ассоциативные массивы.
Т.е. понятие дыры (в индексе) для них чужеродная абстракция.
Есть API (а именно - first/last/next/prior) - где никаких проблем


еще раз -

for i in 1..xxtest.count loop
 dbms_output.put_line(xxtest(i).x1);
end loop;

считаем что код не мой, менять нельзя
я в тот API лазил - там написано именно так "for i in 1..xxtest.count loop"
Elic
Дата: 12.11.2008 14:40:25
nxx
получаю таблицу входным параметром
фильтрую её
возвращаю выходным параметром
for i in 1..inArr.count loop
  if <фильтрую> then
    outArr(outArr.count + 1) := inArr(i);
nxx
Дата: 12.11.2008 14:49:53
Elic
nxx
получаю таблицу входным параметром
фильтрую её
возвращаю выходным параметром
for i in 1..inArr.count loop
  if <фильтрую> then
    outArr(outArr.count + 1) := inArr(i);


а вот это, пожалуй, пойдет
thnx
andrey_anonymous
Дата: 12.11.2008 15:31:49
exec dbms_session.free_unused_user_memory;
set serveroutput on
clear
set echo off
set feedback off

prompt Тест1: влияние порядка вставки и удаления элементов на объем, занимаемый ассоциативным prompt (Run1 - удаление с последующей вставкой, Run2 - вставка с последующим удалением)
declare
  type p1 is record(i int);
  type tp1 is table of p1 index by binary_integer;
  t tp1;
  procedure print_stats(cmnt in varchar2) is 
    cursor stats is select sn.name nm, s.value vl from v$mystat s, v$statname sn where s.STATISTIC# = sn.STATISTIC# and sn.name like 'session pga memory';
    r stats%rowtype;
  begin
    for i in stats loop
      dbms_output.put_line (cmnt||': '||i.nm||'='||i.vl);
    end loop;
  end;
begin
  dbms_session.free_unused_user_memory;
  print_stats('Run1 Base ');
  for i in 1..100000 loop
    if i>1 then t.delete(i-1); end if;
    t(i).i := i;
  end loop;
  print_stats('Run1 Array');
  t.delete;
  dbms_session.free_unused_user_memory;
  print_stats('Run1 Clean');
end;
/

declare
  type p1 is record(i int);
  type tp1 is table of p1 index by binary_integer;
  t tp1;
  procedure print_stats(cmnt in varchar2) is 
    cursor stats is select sn.name nm, s.value vl from v$mystat s, v$statname sn where s.STATISTIC# = sn.STATISTIC# and sn.name like 'session pga memory';
    r stats%rowtype;
  begin
    for i in stats loop
      dbms_output.put_line (cmnt||': '||i.nm||'='||i.vl);
    end loop;
  end;
begin
  dbms_session.free_unused_user_memory;
  print_stats('Run2 Base ');
  for i in 1..100000 loop
    t(i).i := i;
    if i>1 then t.delete(i-1); end if;
  end loop;
  print_stats('Run2 Array');
  t.delete;
  dbms_session.free_unused_user_memory;
  print_stats('Run2 Clean');
end;
/

prompt Тест2: влияние структуры массива на объем памяти, выделяемый под него (Run3 - table of record(int), Run4 - table of int)
declare
  type p1 is record(i int);
  type tp1 is table of p1 index by binary_integer;
  t tp1;
  procedure print_stats(cmnt in varchar2) is 
    cursor stats is select sn.name nm, s.value vl from v$mystat s, v$statname sn where s.STATISTIC# = sn.STATISTIC# and sn.name like 'session pga memory';
    r stats%rowtype;
  begin
    for i in stats loop
      dbms_output.put_line (cmnt||': '||i.nm||'='||i.vl);
    end loop;
  end;
begin
  dbms_session.free_unused_user_memory;
  print_stats('Run3 Base ');
  for i in 1..100000 loop
    t(i).i := i;
  end loop;
  print_stats('Run3 Array');
end;
/

declare
  --type p1 is record(i int);
  type tp1 is table of INT index by binary_integer;
  t tp1;
  procedure print_stats(cmnt in varchar2) is 
    cursor stats is select sn.name nm, s.value vl from v$mystat s, v$statname sn where s.STATISTIC# = sn.STATISTIC# and sn.name like 'session pga memory';
    r stats%rowtype;
  begin
    for i in stats loop
      dbms_output.put_line (cmnt||': '||i.nm||'='||i.vl);
    end loop;
  end;
begin
  dbms_session.free_unused_user_memory;
  print_stats('Run4 Base ');
  for i in 1..100000 loop
    t(i) := i;
  end loop;
  print_stats('Run4 Array');
end;
/
Результат:
Тест1: влияние порядка вставки и удаления элементов на объем, занимаемый ассоциативным массивом
(Run1 - удаление с последующей вставкой, Run2 - вставка с последующим удалением)
 
Run1 Base : session pga memory=2264904
Run1 Array: session pga memory=2264904
Run1 Clean: session pga memory=2264904
 
Run2 Base : session pga memory=2264904
Run2 Array: session pga memory=20090696
Run2 Clean: session pga memory=2264904

Тест2: влияние структуры массива на объем памяти, выделяемый под него (Run3 - table of record(int), Run4 - table of int)
 
Run3 Base : session pga memory=2264904
Run3 Array: session pga memory=20090696
 
Run4 Base : session pga memory=2264904
Run4 Array: session pga memory=8752968
 
SQL>