将旧外连接转换为ANSI

时间:2011-01-25 17:26:17

标签: sql oracle outer-join

我遇到了以下遗留的PL / SQL,并且发现针对标量常量的外连接有些令人困惑。首先,有人可以确认我将此转换为ANSI的尝试是正确的。

遗产代码

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;

如果这是正确的,那么我没有看到使用外连接的意义。当然,如果表 iit 中的主键 it_id 在表 iip 中没有相应的外键,那么 iip.iit_change_type iip.iel_id 将为NULL,在这种情况下,它们将被AND子句过滤掉。那么为什么不使用内连接呢?我错过了什么吗?或原始代码是废话?

3 个答案:

答案 0 :(得分:6)

不,它不正确 - 只有标有“(+)”的那些需要在LEFT JOIN中,其余的都是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  

放置与OUTER JOIN有关 - ON子句中的条件在JOIN之前应用,而WHERE中的条件在JOIN之后应用 。这可能会极大地影响返回的结果集,具体取决于数据和设置。对于INNER JOINS,放置无关紧要 - 在WHERE或ON子句中,结果集将是相同的。

答案 1 :(得分:3)

不,这不对。原始查询中只有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' ; 

答案 2 :(得分:0)

它也可以像这样重写:

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的连接,here is a tool可以帮助您自动执行此操作,并且不易出错。