Home » SQL & PL/SQL » SQL & PL/SQL » update statement with embedded select -- wierd results?
update statement with embedded select -- wierd results? [message #21329] Fri, 26 July 2002 07:49 Go to next message
Son Nguyen
Messages: 8
Registered: July 2002
Junior Member
Hello,

I have two tables, T1 and T2.

Both tables have a field called ID and PartNum.

T1 has 20 records, T2 has 10 records.

SQL:
UPDATE T1 SET T1.PartNum =
(SELECT T2.PartNum FROM T2 WHERE T2.ID = T1.ID)

SQL*Loader returns that 20 records were updated, but there are only 10 records that match on the ID join. I looked at the table and it updated the PartNum on T1 correctly on the matching joins, but the ones it DID NOT match it SET IT TO NULL. I usually use MS SQL Server which allows you to do INNER JOIN tables and it would only update the records where the ID matched. Any thoughts?

Thanks.
Son Nguyen
Re: update statement with embedded select -- wierd results? [message #21330 is a reply to message #21329] Fri, 26 July 2002 07:55 Go to previous messageGo to next message
Son Nguyen
Messages: 8
Registered: July 2002
Junior Member
I said SQL*Loader in my previous message, I MEANT SQL*Plus. Thanks again in advance.
Re: update statement with embedded select -- wierd results? [message #21332 is a reply to message #21329] Fri, 26 July 2002 08:05 Go to previous messageGo to next message
Mahesh Rajendran
Messages: 10707
Registered: March 2002
Location: oracleDocoVille
Senior Member
Account Moderator
the correct syntax is
UPDATE T1 SET T1.PartNum =
(SELECT T2.PartNum FROM T2,T1 WHERE T2.ID = T1.ID)

Re: update statement with embedded select -- wierd results? [message #21336 is a reply to message #21329] Fri, 26 July 2002 08:27 Go to previous messageGo to next message
Son Nguyen
Messages: 8
Registered: July 2002
Junior Member
Hello,

I tried that with my real scenario and it get an error of ERROR at line 2: ORA-01427: single-row subquery returns more than one row

Here is the real SQL statement, basically the same but with more joins:
UPDATE TEMP SET TEMP.PartID =
(SELECT Part.PartID FROM Part, TEMP WHERE
Part.PartNum = TEMP.PartNum AND Part.PartNumExt = TEMP.PartNumExt AND Part.UOM = TEMP.UOM AND Part.SupplierID = 1)

Thanks again.
Re: update statement with embedded select -- wierd results? [message #21339 is a reply to message #21336] Fri, 26 July 2002 09:36 Go to previous messageGo to next message
Todd Barry
Messages: 4819
Registered: August 2001
Senior Member
The behavior you saw (non-matching rows were updated to NULL) is the expected behavior. To preserve the data in rows where there is no match, you need to either use a WHERE EXISTS clause or NVL on the result. In either case, do not include another reference to the base table (TEMP) in the subquery - it should be a correlated subquery instead:

update temp t
   set partid = (select p.partid
                   from part p
                  where p.partnum = t.partnum
                    and p.partnumext = t.partnumext
                    and p.uom = t.uom
                    and p.supplierid = 1)
 where exists
   (select null
      from part p
     where p.partnum = t.partnum
       and p.partnumext = t.partnumext
       and p.uom = t.uom
       and p.supplierid = 1);


Alternatively:

update temp t
   set partid = nvl((select p.partid
                       from part p
                      where p.partnum = t.partnum
                        and p.partnumext = t.partnumext
                        and p.uom = t.uom
                        and p.supplierid = 1), partid);


Option 2 does update each row but sets the partid to the old value instead of NULL when no match is found. This "fake" update may not be desirable in certain situations (rollback size, triggers, etc.), but it does avoid the dual lookup.

With either approach, the subquery must return at most a single row.
Re: update statement with embedded select -- wierd results? [message #21344 is a reply to message #21336] Fri, 26 July 2002 13:32 Go to previous messageGo to next message
Son Nguyen
Messages: 8
Registered: July 2002
Junior Member
Thanks for the help! I got around it this way:

update temp t set partid =
(select p.partid from part p
where p.partnum = t.partnum and p.partnumext = t.partnumext and p.uom = t.uom and p.supplierid = 1)
where (t.partnum, t.partnumext, t.uom) in (select partnum, partnumext, uom from part)

you did something similiar but used where EXISTS instead.. which one is better in this case?

thanks again!
Re: update statement with embedded select -- wierd results? [message #21346 is a reply to message #21344] Fri, 26 July 2002 14:35 Go to previous messageGo to next message
Todd Barry
Messages: 4819
Registered: August 2001
Senior Member
You have extremely small tables, so the difference is irrelevent, but on bigger tables, the WHERE IN approach would require an index on the base table (TEMP) AND an index on the lookup table.

The WHERE EXISTS approach requires just an index on the lookup table (PART).

Also, your approach theoretically could fail if there was a matching entry in part based on partnum, partnumext, and uom - but the supplierid <> 1. I still prefer the WHERE EXISTS approach, but with your example, the main WHERE clause should have been:

where (partnum, partnumext, uom, 1) in (select partnum, partnumext, uom, supplierid) from part);
Oracle query [message #21349 is a reply to message #21329] Sat, 27 July 2002 03:33 Go to previous messageGo to next message
yuvaraj
Messages: 3
Registered: July 2002
Junior Member
In the subquey no need to mention the t2 table in from
statment
then
I have a doubht

what is the query to bring the accumulated salary
for example

1 radha 100
2 raghv 200
3 arjun 400

If I paid 400 Rs totally then it shows Like this

1 radha 100 100
2 raghv 200 200
3 arjun 400 100
Oracle query [message #21894 is a reply to message #21329] Sun, 08 September 2002 20:36 Go to previous messageGo to next message
B.Raghavan
Messages: 1
Registered: September 2002
Junior Member
Dear Sir,

I have the basic doubts :

1) How to create the duplicate table (which need to contain same table structure and data's also)

2) What is the use SID in tnsnames.ora

3) Suppose database is remote side (we are accessing the database from remote through network)
what are all configuration need to be done.

i think surely you will response asap.

thanks and regards
Raghavan.B
Re: update statement with embedded select -- wierd results? [message #21940 is a reply to message #21329] Wed, 11 September 2002 16:47 Go to previous message
Petr Pivonka
Messages: 1
Registered: September 2002
Junior Member
My suggestion is quite late for, but I solve the same problem just now and following statement works reliably:

UPDATE tab1, tab2
SET tab1.col1 = tab2.col1
WHERE tab1.col2 = tab2.col2

I didn't get any NULL settings of tab1.col1 in the case of non-matching joins. I only suppose redundant processing when tab2.col2 has duplicity.
Previous Topic: stored procedure called from c code with varying arguments
Next Topic: help
Goto Forum:
  


Current Time: Thu May 02 18:40:28 CDT 2024