Преобразование устаревшего внешнего соединения в ANSI - PullRequest
0 голосов
/ 25 января 2011

Я наткнулся на следующий унаследованный PL / SQL и нахожу несколько запутанными внешние объединения против скалярных констант. Прежде всего, кто-то может подтвердить, что моя попытка преобразовать это в ANSI верна.

LEGACY CODE :

cursor c1item (c1item_iel_id number) is  
select  
  `<columns>`  
from  iel_item iit, iel_item_property iip  
  where iit.iit_change_type = 'I'  
  and   iip.iip_change_type (+) = 'I'  
  and   iip.it_id (+)  = iit.it_id  
  and   iit.iel_id = c1item_iel_id  
  and   iip.iel_id (+) = c1item_iel_id;

ANSI CODE

cursor c1item (c1item_iel_id number) is  
select  
   `<columns>`  
from  iel_item iit  
left outer join iel_item_property iip  
on  iip.it_id = iit.it_id  
    and  iit.iit_change_type = 'I'  
    and  iip.iip_change_type = 'I'  
    and  iit.iel_id = c1item_iel_id  
    and  iip.iel_id = c1item_iel_id;

Если это правильно, то я не вижу смысла в использовании внешнего соединения. Конечно, если первичный ключ it_id в таблице iit не имеет соответствующего внешнего ключа в таблице iip , то оба iip.iit_change_type и iip.iel_id будет иметь значение NULL, и в этом случае они будут отфильтрованы предложениями AND. Так почему бы просто не использовать внутреннее соединение? Я что-то пропустил? или это оригинальный код чепухи?

Ответы [ 3 ]

6 голосов
/ 25 января 2011

Нет, это не правильно - только те, которые отмечены знаком "(+)", должны быть в левом соединении, остальное для предложения WHERE:

   SELECT `<columns>`  
     FROM iel_item iit  
LEFT JOIN iel_item_property iip  ON iip.it_id = iit.it_id  
                                AND iip.iip_change_type = 'I'  
                                AND iip.iel_id = c1item_iel_id
    WHERE iit.iit_change_type = 'I'      
      AND iit.iel_id = c1item_iel_id  

Размещение имеет значение с внешними соединениями- критерии в предложении ON применяются до JOIN, а критерии в WHERE применяются после JOIN.Это может сильно повлиять на возвращаемый набор результатов, зависит от данных и настроек.Размещение не имеет значения для INNER JOINS - в выражении WHERE или ON набор результатов будет таким же.

3 голосов
/ 25 января 2011

Нет, это не правильно. В исходном запросе было только 3 предиката внешнего соединения, у вашего нового - все 5.

Должно быть:

cursor c1item (c1item_iel_id number) is  
select  
   `<columns>`  
from  iel_item iit  
left outer join iel_item_property iip  
on  iip.it_id = iit.it_id  
    and  iip.iip_change_type = 'I'  
    and  iip.iel_id = c1item_iel_id
where    and  iit.iel_id = c1item_iel_id  
    and  iit.iit_change_type = 'I' ; 
0 голосов
/ 20 января 2012

Его также можно переписать следующим образом:

SELECT columns1
FROM   iel_item iit
       RIGHT OUTER JOIN iel_item_property iip
         ON iip.iip_change_type = 'I'
            AND iip.it_id = iit.it_id
            AND iip.iel_id = c1item_iel_id
WHERE  iit.iit_change_type = 'I'   
        AND iit.iel_id = c1item_iel_id

В следующий раз, если вам нужно переписать собственные соединения Oracle в соединения, совместимые с ANSI SQL, вот инструмент , который может помочьВы делаете это автоматически с меньшим количеством ошибок.

...