views:

50

answers:

2

Works:

AND UPPER(a.name) = b.lname(+)

does not work

AND UPPER(a.name) = UPPER(b.lname) (+)

Moving to ANSI joins is an option but a painstaking one. This code should be changed in lot of places and there are lot of joins. I would like to get this syntax correct and be on my way.

Is it possible?

+3  A: 

It is quite possible that the second version of the code will not work, ever. If it wasn't in use before, it is all the more plausible that it won't work. (See the accepted answer for how to use the obsolesent notation. I still think that the rest of the advice below stands - but note carefully the qualifier 'when you need to modify the SQL'; if you don't need to change the SQL for some other reason, there's no necessity to remove the old-style notation.)

Bite the bullet and deal with the ANSI join when you need to do the case-insensitive comparison. Or investigate a locale-based alternative (with case-insensitive comparisons), if such an option exists in Oracle.

Fundamentally, though, you should consign the old '(+)' outer join notation to the trash can. When you have to modify an SQL statement, remove the old (obsolescent) notation and use the ANSI join notation instead.


A comment asks 'how can this be converted to ANSI'?

You rewrite the FROM clause as well as the WHERE clause - often moving join conditions from the WHERE clause to the ON conditions in the FROM clause.

 SELECT a.*, b.*
   FROM a LEFT OUTER JOIN b ON UPPER(a.name) = UPPER(b.lname)

Another comment asks 'how to extend the join to three tables'?

 SELECT a.*, b.*
   FROM a 
     LEFT OUTER JOIN b ON UPPER(a.name) = UPPER(b.lname)
     LEFT OUTER JOIN c ON on a.first = c.first
Jonathan Leffler
+1: My sentiments exactly.
OMG Ponies
what if a needs to be outer joined with another table , say, c. then do we do ? `FROM a LEFT OUTER JOIN b ON UPPER(a.name) = UPPER(b.name), a LEFT OUTER JOIN c on a.first = c.first`
learn_plsql
"It is quite possible that the second version of the code will not work, ever." - actually it does work, with the correct placement of brackets.
APC
@Gary: thanks for the three-table join edit!
Jonathan Leffler
I too prefer the new skool outer joins too, but there are good reasons for using the `(+)` notation. Not the least of which is that Oracle 8i (not to mention earlier versions) remains in widespread use, even if it is no longer supported.
APC
+5  A: 

Yuckiness aside, incorporating UPPER() with the old skool OUTER JOIN syntax is simplicity itself: we just need to get the brackets in the right order:

SQL> select t23.name
  2         , d.university
  3  from t23
  4       , t_doctors d
  5  where upper(t23.name) = upper(d.name(+))
  6  order by t23.id
  7  /

NAME         UNIVERSITY
------------ --------------------
SAM-I-AM
MR KNOX
FOX IN SOCKS
CAT
LORAX
BILLY
MAISIE
DR SINATRA   Whoville U
DR FONZ      U of Grin-itch
PINNER BLINN

10 rows selected.

SQL> 

Here is how to deploy the newer syntax with multiple tables:

SQL> select t23.name
  2         , d.university
  3         , k.school
  4  from t23
  5       left outer join t_doctors d
  6                  on upper(t23.name) = upper(d.name)
  7       left outer join t_kids k
  8                  on upper(t23.name) = upper(k.name)
  9  order by t23.id
 10  /

NAME         UNIVERSITY           SCHOOL
------------ -------------------- --------------------
SAM-I-AM                          Mulberry St Junior
MR KNOX
FOX IN SOCKS
CAT
LORAX
BILLY                             Roover River High
MAISIE                            Roover River High
DR SINATRA   Whoville U
DR FONZ      U of Grin-itch
PINNER BLINN

10 rows selected.

SQL>
APC
+1: Interesting, I hope I never have to remember the trick though :)
OMG Ponies
does adding UPPER mean that index will not be used? I know indexes are not used if we add trim
learn_plsql
@learn_plsql - that's a separate question ;) The short answer is you're correct, but there are workarounds.
APC