ORA-01719:OR或IN的操作数中不允许使用外部联接运算符(+)

时间:2018-06-27 04:29:01

标签: sql oracle

运行查询时出现错误:

  

ORA-01719:OR或IN的操作数中不允许使用外部联接运算符(+)   01719. 00000-“在OR或IN的操作数中不允许使用外部联接运算符(+)”

     

原因:外部联接出现在or子句中。

     

操作:如果A和B是谓词,则要获得(A(+)或B)的效果,              尝试(选择(A(+)而不是B))全部合并(选择(B)地方)

由于我在最后定义的where子句中的AND或条件,我遇到了此错误。

SELECT DISTINCT rp.rp_record_id,
                rp.rate_profile_name,
                rph.rate_type,
                rph.charge_code,
                rph.transport_mode,
                rph.place_of_receipt_code,
                rph.origin_type,
                rph.destination_type
  FROM rate_profile rp,
       rate_profile_header rph,
       partner_charge_profile pcp,
       partner,
       commodity_codes com,
       offices,
       partner_relationships pr,
       company_partners cp,
       employee e
 WHERE        rp.rp_record_id = rph.rp_record_id
          AND pcp.partner_id = partner.partner_id
          AND rph.commcode_record_id = com.cc_record_id(+)
          AND pcp.company_id = offices.company_id
          AND offices.office_type = 'T'
          AND partner.partner_id = pr.partner_id(+)
          AND pr.employee_no = e.employee_no
          AND partner.partner_id = cp.partner_id
          AND cp.company_id = '&CompanyID'
          AND cp.company_id = pcp.company_id
          AND cp.company_id(+) = pr.company_id
          AND pcp.charge_code = rph.charge_code
          AND pcp.charge_calculation_method = 'R'
          AND rph.rp_record_id = pcp.charge_rateprof_record_id
          AND (    ('&psRate_type') = 'SEL'
               AND (    rph.rate_type = 'SEL'
                    AND pcp.charge_calculation_method = 'R'
                    AND rph.rp_record_id = pcp.charge_rateprof_record_id))
       OR (    ('&psRate_type') = 'BUY'
           AND (    rph.rate_type = 'BUY'
                AND pcp.cost_calculation_method = 'R'
                AND rph.rp_record_id = pcp.cost_rateprof_record_id))
       OR (    ('&psRate_type') = 'All'
           AND (   (    rph.rate_type = 'SEL'
                    AND pcp.charge_calculation_method = 'R'
                    AND rph.rp_record_id = pcp.cost_rateprof_record_id)
                OR (    (rph.rate_type = 'BUY')
                    AND pcp.cost_calculation_method = 'R'
                    AND rph.rp_record_id = pcp.cost_rateprof_record_id)))

请提出建议

1 个答案:

答案 0 :(得分:1)

外部联接错误消息中提到的OR条件在'&psRate_type'过滤器部分中,我认为您不打算成为联接的一部分。如果将所有这些条件括在AND谓词中,则错误将消失:

select distinct
       rp.rp_record_id
     , rp.rate_profile_name
     , rph.rate_type
     , rph.charge_code
     , rph.transport_mode
     , rph.place_of_receipt_code
     , rph.origin_type
     , rph.destination_type
from   rate_profile           rp
     , rate_profile_header    rph
     , partner_charge_profile pcp
     , partner
     , commodity_codes        com
     , offices
     , partner_relationships  pr
     , company_partners       cp
     , employee               e
where  rp.rp_record_id = rph.rp_record_id
and    pcp.partner_id = partner.partner_id
and    com.cc_record_id (+) = rph.commcode_record_id
and    pcp.company_id = offices.company_id
and    offices.office_type = 'T'
and    pr.partner_id (+) = partner.partner_id
and    pr.employee_no = e.employee_no
and    partner.partner_id = cp.partner_id
and    cp.company_id = '&CompanyID'
and    cp.company_id = pcp.company_id
and    cp.company_id (+) = pr.company_id
and    pcp.charge_code = rph.charge_code
and    pcp.charge_calculation_method = 'R'
and    rph.rp_record_id = pcp.charge_rateprof_record_id
-- Added brackets below:
and    (    ('&psRate_type' = 'SEL' and rph.rate_type = 'SEL' and pcp.charge_calculation_method = 'R' and rph.rp_record_id = pcp.charge_rateprof_record_id)
        or  ('&psRate_type' = 'BUY' and rph.rate_type = 'BUY' and pcp.cost_calculation_method = 'R' and rph.rp_record_id = pcp.cost_rateprof_record_id)
        or  ('&psRate_type' = 'All'
             and (    (rph.rate_type = 'SEL' and pcp.charge_calculation_method = 'R' and rph.rp_record_id = pcp.cost_rateprof_record_id)
                  or  (rph.rate_type = 'BUY' and pcp.cost_calculation_method   = 'R' and rph.rp_record_id = pcp.cost_rateprof_record_id))
            )
       );

但是,company_partners实际上不能成为外部联接,因为cp.company_id = '&CompanyID'partner_relationships也是如此,因为pr.employee_no = e.employee_no。唯一真正的外部联接是commodity_codes,无论如何该联接都不会在查询中使用,并且可以在不影响结果的情况下将其删除。

考虑到这一点,我将得到以下内容作为ANSI版本:

select distinct
       rp.rp_record_id
     , rp.rate_profile_name
     , rph.rate_type
     , rph.charge_code
     , rph.transport_mode
     , rph.place_of_receipt_code
     , rph.origin_type
     , rph.destination_type
from   company_partners cp
       join partner_relationships  pr
            on  pr.company_id = cp.company_id
            and pr.partner_id = cp.partner_id
       /*join partner  -- not needed if pr.partner_id is a FK to partner
            on  partner.partner_id = pr.partner_id*/
       join partner_charge_profile pcp
            on  pcp.company_id = cp.company_id
            and pcp.partner_id = cp.partner_id
       join rate_profile_header rph
            on  rph.charge_code = pcp.charge_code
            and rph.rp_record_id = pcp.charge_rateprof_record_id
       join rate_profile rp
            on  rp.rp_record_id = rph.rp_record_id
       join employee e
            on  e.employee_no = pr.employee_no
       join offices
            on  offices.company_id = pcp.company_id
       /*left join commodity_codes com  -- not used
            on  com.cc_record_id = rph.commcode_record_id*/
where  cp.company_id = '&CompanyID'
and    pcp.charge_calculation_method = 'R'
and    offices.office_type = 'T'
and    (    ('&psRate_type' = 'SEL' and rph.rate_type = 'SEL' and pcp.charge_calculation_method = 'R')
        or  ('&psRate_type' = 'BUY' and rph.rate_type = 'BUY' and pcp.cost_calculation_method = 'R' and rph.rp_record_id = pcp.cost_rateprof_record_id)
        or  ('&psRate_type' = 'All' 
             and (    (rph.rate_type = 'SEL' and pcp.charge_calculation_method = 'R' and rph.rp_record_id = pcp.cost_rateprof_record_id)
                  or  (rph.rate_type = 'BUY' and pcp.cost_calculation_method = 'R' and rph.rp_record_id = pcp.cost_rateprof_record_id)))
       );