CftClub.ru
Клуб специалистов ЦФТ-Банк

в чем ошибка?

 
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Разработка в PL/PLUS. Оптимизация запросов Oracle
Предыдущая тема :: Следующая тема  
Автор Сообщение
wolfio
Участник - экстремал


Вступление в Клуб: 22.10.2012
СообщениеСр Дек 09, 2015 11:30   в чем ошибка? Ответить с цитатой
Полезность: Нет оценки
здравствуйте.

пишу вроде бы простой отчетик, и споткнулся на самом простом.
создал переменную табличного типа, заполнил ее, убираю в ней дубли ссылок и получаю ошибку "данные не найдены".

Код:

type blckTbleType is table of ref [BLACKLIST];       
blckTble       blckTbleType;

begin
--заполняю
blckTble:= ::[BLACKLIST].[LIB].check_bl_doc_list(mdoc%ID); --дополнительная проверка клиента. Аналогия операции CHANGE_SUSPECT.
            tbClient := ::[BLACKLIST].[lib].check_em_get_clients(mdoc);
            for i in tbClient.first..tbClient.last loop
               blckTbleDOP := ::[BLACKLIST].[lib].check_bl_client_list(tbClient(i).cl);
               if blckTbleDOP.count > 0 then
                  for j in blckTbleDOP.first..blckTbleDOP.last loop
                     blckTble(blckTble.count+1):=blckTbleDOP(j);
                  end loop;
               blckTbleDOP.delete;
               end if;
            end loop;

--убиваю дубли
      for j in blckTble.first..blckTble.last loop
                     if j<>i then
                        if blckTble(j) = blckTble(i) then --ошибка при выполнении выдается тут
                           blckTble(i) := null;
                        end if;
                     end if;
                  end loop;
               end loop;

end;


в таблице вроде как допускаются пустые строки. но я не понимаю, почему возникает ошибка? может кто сталкивался?
Volod
Эксперт


Вступление в Клуб: 19.09.2007
СообщениеСр Дек 09, 2015 11:43    Ответить с цитатой
Полезность: Нет оценки
Там, где требуются сортировка и группировка - я использую временные Oracle таблицы.
danzki
Участник - экстремал


Вступление в Клуб: 30.09.2010
СообщениеСр Дек 09, 2015 13:00    Ответить с цитатой
Полезность: 1
это assosiated array при удалении элемента сдвиг не происходит, остается просто "дырка".
Вариант решения завести еще один массив такого же типа, копировать в него элементы из оригинала без дубликатов (пропуская дубликаты при переборе). Затем очистить исходный и присвоить ему временный.

Типа
tbClient.delete;
tbClient := tmpClient;
Amper
Профи


Вступление в Клуб: 29.10.2010
СообщениеСр Дек 09, 2015 13:52   Re: в чем ошибка? Ответить с цитатой
Полезность: Нет оценки
Лень разбираться, но вроде проблема в отсеивании дублей, тогда можно так:
Код:
  declare
     type tpVarray is varray(0) of ref [BLACKLIST];
     blckVarray     tpVarray;
     nullVarray   tpVarray;
  begin
      blckVarray := blckTble;
      blckTble   := blckVarray MULTISET MINUS DISTINCT nullVarray;
  end;

При этом происходит копирование из таблицы в varray и обратно, поэтому лучше сразу заводить varray, чтобы избежать копирования.
KhrushchevAV
Участник со стажем


Вступление в Клуб: 17.10.2014
СообщениеЧт Дек 10, 2015 06:50    Ответить с цитатой
Полезность: Нет оценки
А мне кажется, проблема в другом. Может вы, конечно, просто код не удачно скопировали, но, в том куске, который мне видно нет второго цикла по i. А первый цикл по i уже закончен. Тогда обращение к i не корректно.
wolfio
Участник - экстремал


Вступление в Клуб: 22.10.2012
СообщениеЧт Дек 10, 2015 10:46    Ответить с цитатой
Полезность: Нет оценки
в общем все еще больше усложнилось.

как я теперь понял, дистрибутив сам заполняют эту табличную переменную "дыркой", к которой нельзя обратиться:

Код:

declare
type blckTbleType is table of ref [BLACKLIST];       
blckTble       blckTbleType;

begin

blckTble:= ::[BLACKLIST].[LIB].check_bl_doc_list(mdoc%ID);
   for u in 1..blckTble.count loop
      debug_pipe(blckTble(u).name,0); --ошибка будет тут
   end loop;
end;


при этом blckTble(u).count = 1. как понять, что вообще есть в этой записи? и как избавиться от нее, не создавая varray? вариант с копией переменной не подходит, т.к. при их сравнении тоже ошибка возникнет.
vtar
Эксперт


Вступление в Клуб: 20.03.2009
СообщениеЧт Дек 10, 2015 11:12    Ответить с цитатой
Полезность: 1
wolfio,
если спотыкается на дырке
или используй вместо first-last конструкцию first - next
Код:

     cnt := p_List.first;
     while not (cnt is null) loop
         cr_ref := p_List(cnt);
         begin
         exception
         end;
         cnt := p_List.next(cnt);
     end loop;





или , проверяй .exists


Последний раз редактировалось: vtar (Чт Дек 10, 2015 11:12), всего редактировалось 1 раз
Admin
Site Admin


Вступление в Клуб: 09.06.2007
СообщениеЧт Дек 10, 2015 11:12    Ответить с цитатой
Полезность: 1
Код:

   if blckTble(u).exists = false then
      debug_pipe('ошибки не будет',0);
   end if
wolfio
Участник - экстремал


Вступление в Клуб: 22.10.2012
СообщениеЧт Дек 10, 2015 11:24    Ответить с цитатой
Полезность: Нет оценки
так не работает

Код:

            for u in 1..blckTble.count loop
               if blckTble.exists(u) = false then
                  debug_pipe(blckTble(u).name,0); --ошибка
               else
                  debug_pipe('empty',0);
               end if;
            end loop;


а так работает
Код:

         vCnt := blckTble.first;
              while not (vCnt is null) loop
                  debug_pipe(blckTble(vCnt).name,0);
                  vCnt := blckTble.next(vCnt);
              end loop;

в дебаг падает
JOINT STOCK COMPANY 'AEROFLOT- RUSSIAN AIRLINES

в чем прикол? Получается, что индекс первой строки не с 1 начинается?
vtar
Эксперт


Вступление в Клуб: 20.03.2009
СообщениеЧт Дек 10, 2015 11:34    Ответить с цитатой
Полезность: Нет оценки
wolfio пишет:

в чем прикол? Получается, что индекс первой строки не с 1 начинается?


дык, выводи значения vCnt, в чом проблема

и кстати, .exists = falsе нет такого элемента, а ты его пытаешся достать
wolfio
Участник - экстремал


Вступление в Клуб: 22.10.2012
СообщениеЧт Дек 10, 2015 11:38    Ответить с цитатой
Полезность: Нет оценки
vtar пишет:
wolfio пишет:

в чем прикол? Получается, что индекс первой строки не с 1 начинается?


дык, выводи значения vCnt, в чом проблема

и кстати, .exists = falsе нет такого элемента, а ты его пытаешся достать


да это я как бы сам себе) нулевой индекс у этой строки)
Эмиралька
Эксперт


Вступление в Клуб: 09.11.2015
СообщениеПн Дек 14, 2015 14:44    Ответить с цитатой
Полезность: 1
обратный цикл рулит.
for i in REVERSE 1 .. blckTble.count loop
vtar
Эксперт


Вступление в Клуб: 20.03.2009
СообщениеПн Дек 14, 2015 15:57    Ответить с цитатой
Полезность: Нет оценки
Эмиралька пишет:
обратный цикл рулит.
for i in REVERSE 1 .. blckTble.count loop

Как это поможет, если дыры будут в середине ?
Эмиралька
Эксперт


Вступление в Клуб: 09.11.2015
СообщениеВт Дек 15, 2015 06:59    Ответить с цитатой
Полезность: Нет оценки
vtar пишет:
Эмиралька пишет:
обратный цикл рулит.
for i in REVERSE 1 .. blckTble.count loop

Как это поможет, если дыры будут в середине ?


Вот так:
Код:

for i in reverse 1 .. blckTble.count loop
   if критерий_обнаружения_дубля_сработал then
      if i < blckTble.count then
         blckTble(i) := blckTble(blckTble.count);
      end if;
      blckTble.delete(blckTble.count);
   end if;
end loop;

И никаких дырок.
Показать сообщения:   
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Разработка в PL/PLUS. Оптимизация запросов Oracle Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Рейтинг@Mail.ru