Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
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;
|
И никаких дырок. |
|
 |
|