Интерпретация условия «OR» из PL/PLUS в PL/SQL
|
Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
VSV056 Участник - экстремал
Вступление в Клуб: 25.11.2010
|
Вт Мар 24, 2015 07:57  Интерпретация условия «OR» из PL/PLUS в PL/SQL |
|
Полезность: Нет оценки
|
Коллеги, доброго дня!
Столкнулись с несколько непонятной работой интерпретатора PL/PLUS.
Задача: проверить условие того, что хотя бы один из счетов дебета или кредита платежного документа относятся к внебалансу, главе Г.
Логически приходящее решение (упрощенный синтаксис): [ACC_DT] = 'Г' OR [ACC_KT] = 'Г'
Пишем код, запускаем, получаем что все документы в выборке задваиваются. Удивляемся, т.к. логически вроде все верно.
Смотрим во что преобразовалось наше условие в PL/SQL - оказывается [AC_FIN]
в итоговой выборке JOIN-ться к [MAIN_DOCUM] только один раз, в итоге в выборку один и тот же документ попадает дважды, если оба условия соединенные "OR" выполняются.
Скажите оно всегда так работало?
Или можно каким-то образом указать интерпретатору на необходимость нового JOINа [AC_FIN] для каждого условия "ИЛИ"?
Ниже пример кода, где первый вариант - с задвоением, второй рабочий.
Код: | begin
debug_pipe('первый вариант',10);
for v_doc in ::[MAIN_DOCUM] all
where ( v_doc.[ACC_DT].[MAIN_USV].[USV_US].[NEW_BS1].[RASD].[CHAPTER].[CHAPTER]='Г'
or
v_doc.[ACC_KT].[MAIN_USV].[USV_US].[NEW_BS1].[RASD].[CHAPTER].[CHAPTER]='Г'
)
and v_doc=6830826889
loop
debug_pipe('v_doc = '||v_doc,10);
end loop;
debug_pipe('второй вариант',10);
for v_doc in ::[MAIN_DOCUM] all
where 'Г' in ( v_doc.[ACC_DT].[MAIN_USV].[USV_US].[NEW_BS1].[RASD].[CHAPTER].[CHAPTER]
,v_doc.[ACC_KT].[MAIN_USV].[USV_US].[NEW_BS1].[RASD].[CHAPTER].[CHAPTER]
)
and v_doc=6830826889
loop
debug_pipe('v_doc = '||v_doc,10);
end loop;
end; |
Результат работы:
16:56:01 первый вариант
v_doc = 6830826889
v_doc = 6830826889
второй вариант
v_doc = 6830826889 |
|
|
Gobur Профи
Вступление в Клуб: 06.11.2012
|
Вт Мар 24, 2015 10:16  Re: Интерпретация условия «OR» из PL/PLUS в PL/SQL |
|
Полезность: Нет оценки
|
Думаю тут дело в слишком глубокой вложенности на ПЛ+, что заставляет ядро автоматом связывать еще несколько таблиц. Тут либо самом эту связку прописывать ТБП, либо действительно IN использовать. Опять же эт она мой взгляд. |
|
|
Damir Участник - экстремал
Вступление в Клуб: 29.03.2013
|
Вт Мар 24, 2015 11:06  Re: Интерпретация условия «OR» из PL/PLUS в PL/SQL |
|
Полезность: Нет оценки
|
Gobur прав.
в запросах ПЛ+ обращение к каждому 'более вложенному' атрибуту приводит к добавлению таблицы в основной запрос ( в секцию from запроса SQL).
А вообще... жмите F12 и смотрите реальный SQL-запрос - без этого-то никак. |
|
|
Damir Участник - экстремал
Вступление в Клуб: 29.03.2013
|
Вт Мар 24, 2015 11:12  Re: Интерпретация условия «OR» из PL/PLUS в PL/SQL |
|
Полезность: Нет оценки
|
Код: | for v_doc in ::[MAIN_DOCUM] all
where
exists(
select m(m) in ::[MAIN_DOCUM] all
where m = v_doc
and m.[ACC_DT].[MAIN_USV].[USV_US].[NEW_BS1].[RASD].[CHAPTER].[CHAPTER]='Г'
)
or exists(
select m(m) in ::[MAIN_DOCUM] all
where m = v_doc
and m.[ACC_KT].[MAIN_USV].[USV_US].[NEW_BS1].[RASD].[CHAPTER].[CHAPTER]='Г'
)
and v_doc=6830826889
|
тока проверить надо - F12 и посмотреть чего получилось |
|
|
budinva Участник - экстремал
Вступление в Клуб: 15.01.2008
|
Ср Мар 25, 2015 16:03   |
|
Полезность: 1
|
не совсем конечно в тему, но проверять главу можно только по одной стороне, т.к. корреспонденция счетов с разными главами запрещена |
|
|
Random Эксперт
Вступление в Клуб: 27.06.2011
|
Чт Мар 26, 2015 12:31  Re: Интерпретация условия «OR» из PL/PLUS в PL/SQL |
|
Полезность: Нет оценки
|
VSV056 пишет: |
Пишем код, запускаем, получаем что все документы в выборке задваиваются. Удивляемся, т.к. логически вроде все верно.
Код: | begin
debug_pipe('первый вариант',10);
for v_doc in ::[MAIN_DOCUM] all
where ( v_doc.[ACC_DT].[MAIN_USV].[USV_US].[NEW_BS1].[RASD].[CHAPTER].[CHAPTER]='Г'
or
v_doc.[ACC_KT].[MAIN_USV].[USV_US].[NEW_BS1].[RASD].[CHAPTER].[CHAPTER]='Г'
)
and v_doc=6830826889
loop
debug_pipe('v_doc = '||v_doc,10);
end loop;
end; |
Результат работы:
16:56:01 первый вариант
v_doc = 6830826889
v_doc = 6830826889
|
На мой взгляд, никакого противоречия нет.
Вы забываете, что переход по ссылке в pl+ - это присоединение таблицы в pl/sql.
То есть вы к документам присоединяете счета. Указываете, что счёт должен совпадать либо с ACC_DT, либо с ACC_KT.
Естественно, в таблице счетов оба счёта есть, то есть каждое из условий срабатывает.
Однако Oracle условие соединения строит несколько другое - выбрать из счетов такие счета, которые совпадают с полями документа дебетовым или кредитовым. Естественно, при такой постановке вопроса, к каждому счёту дублируется документ.
и чему ж вы таки удивляетесь?
Вы ж не написали
Код: | begin
debug_pipe('первый вариант',10);
for v_doc in ::[MAIN_DOCUM] all
where ( v_doc.[ACC_DT] in (select dt(dt) in ::[AC_FIN] where dt.[MAIN_USV].[USV_US].[NEW_BS1].[RASD].[CHAPTER].[CHAPTER]='Г' )
or
v_doc.[ACC_KT] in (select kt(kt) in ::[AC_FIN] where kt.[MAIN_USV].[USV_US].[NEW_BS1].[RASD].[CHAPTER].[CHAPTER]='Г')
)
and v_doc=6830826889
loop
debug_pipe('v_doc = '||v_doc,10);
end loop;
end; |
|
|
|
VSV056 Участник - экстремал
Вступление в Клуб: 25.11.2010
|
Чт Мар 26, 2015 12:47   |
|
Полезность: Нет оценки
|
Цитата: |
На мой взгляд, никакого противоречия нет.
Вы забываете, что переход по ссылке в pl+ - это присоединение таблицы в pl/sql.
То есть вы к документам присоединяете счета. Указываете, что счёт должен совпадать либо с ACC_DT, либо с ACC_KT.
Естественно, в таблице счетов оба счёта есть, то есть каждое из условий срабатывает.
Однако Oracle условие соединения строит несколько другое - выбрать из счетов такие счета, которые совпадают с полями документа дебетовым или кредитовым. Естественно, при такой постановке вопроса, к каждому счёту дублируется документ.
и чему ж вы таки удивляетесь?
|
Все то, что вы расписали, было выяснено и понято еще на этапе анализа ошибки, еще до того как написать сюда (жмем F12 смотрим что получилось в итоговом коде).
Удивление вызвал тот факт, что за все время работы такая ситуация возникла впервые, раньше или подобных случаев не было или мы дважды OR из одной таблицы не делали... )))
Поэтому и удивление и вопрос - оно всегда так работало?
Что еще могу от себя добавить - работа с PL/PLUS притупляет внимательность и отчасти расхолаживает. Смотришь вроде все верно - а по факту не так.
Так что как говорится на PL/PLUS надейся да сам не плошай) |
|
|
Alkov Профи
Вступление в Клуб: 23.09.2010
|
Пт Мар 27, 2015 05:23   |
|
Полезность: 1
|
В любой непонятной ситуации жми F12 |
|
|
|
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
|
|