Subquery in Update
Hi,
Can we use a subquery after the update keyword??
For example
UPDATE ( Select col1 from test)
set col1='x';
In short can we replace the table name after an update and use a select statement instead??
Thanks in advance.
964247 wrote:
Hi,
Can we use a subquery after the update keyword??
For example
UPDATE ( Select col1 from test)
set col1='x';
For reference, you need to research the topic "Updatable Join View" (sometimes written as "Updateable").
If the subquery is a simple select on a single table then Oracle will simply merge the subquery predicate with any predicate you have on the update statement; but if the subquery is a join there are various restrictions (largely to do with the uniqueness, or non-ambiguity, of the thing you want to modify) that may result in you seeing errors about lack of "key preservation" (e.g. http://jonathanlewis.wordpress.com/2008/12/19/updatable-join-views/ )
Regards
Jonathan Lewis
Similar Messages
-
How can i use multiple row subquery in update statement
Hai All
I using group function in my update statement.. and i need to update more rows so i need to use multiple row
subquery pls tell me how to use multiple row subquery in update statement
For example
while i am using this like this i got an error
update dail_att set outtime in (select max(r2.ptime) from temp_att where empcode=r2.enpno and
barcode=r2.cardn and attend_date=r2.pdate group by enpno,pdate,cardn);
Pls tell me how to use with example
Thanks & regards
Srikkanth.MHai Man
Thanks for ur response Let me clear what i need
First step Fetch the records as text file and stores into table T1
and the next step is i have seperated the text using substring and stores in different columns of a table
There are two shifts 0815 to 1645 and 1200 and 2000
Here I rep IN and O rep OUT
Empno date time inout
001 01-01-10 0815 I
002 01-01-10 0815 I
003 01-01-10 0818 I
001 01-01-10 1100 0
001 01-01-10 1130 I
002 01-01-10 1145 0
002 01-01-10 1215 I
004 01-01-10 1200 I
005 01-01-10 1215 I
004 01-01-10 1315 O
004 01-01-10 1345 I
001 01-01-10 1645 0
002 01-01-10 1715 0
003 01-01-10 1718 0
004 01-01-10 2010 0
005 01-01-10 2015 0
This is my T1 table i have taken data from text file and stored in this table from this table i need to move data to another table T2
T2 contains like this
Empno Intime Intrin Introut Outtime Date
001 0815 1100 1130 1645 01-01-10
002 0815 1145 1215 1715 01-01-10
003 0818 1718 01-01-10
004 1200 1315 1345 2010 01-01-10
005 1215 2015 01-01-10
This what i am trying to do man but i have little bit problems Pls give some solution with good example
And my coding is
declare
emp_code varchar2(25);
in_time varchar2(25);
out_time varchar2(25);
Cursor P1 is
Select REASON,ECODE,READMODE,EMPD,ENPNO,FILL,PDATE,PTIME,INOUT,CARDN,READERN
From temp_att
group by REASON,ECODE,READMODE,EMPD,ENPNO,FILL,PDATE,PTIME,INOUT,CARDN,READERN
ORDER BY enpno,pdate,ptime;
begin
for r2 in p1 loop
declare
bar_code varchar2(25);
begin
select barcode into bar_code from dail_att where empcode=r2.enpno and attend_date=r2.pdate;
For r3 in (select empcode,empname,barcode,intime,intrin,introut,addin,addout,outtime,attend_date from dail_att)loop
if r2.inout ='O' then
update dail_att set outtime =(select max(r2.ptime) from temp_att where empcode=r2.enpno and barcode=r2.cardn and attend_date=r2.pdate group by r2.cardn,r2.enpno,r2.pdate );
end if;
end loop;
exception
when no_data_found then
if r2.inout ='I' then
insert into dail_att(barcode,empcode,intime,attend_date)(select r2.cardn,r2.enpno,min(r2.ptime),r2.pdate from temp_att group by r2.cardn,r2.enpno,r2.pdate );
end if;
end;
end loop;
commit;
end;
Pls tell me what correction i need to do i the update statement i have used a subquery with group function but when i used it will return only one row but my need is to return many rows and i need to use multiple row subquery
and how can i use it in the update statement
Thanks In Advance
Srikkanth.M -
Subquery in update not seeing parent value
Hi all,
I'm working on a complex update statement that I will try to state as simply as possible.
update table1 x set value1=(select value1 from table1
where acct_num=x.acct_num
and trans_dt=(select max(trans_dt) from table1 where acct_num=x.acct_num and [many more conditions])
[and many more conditions]All of this is working fine. Where I reach the problem is when I need to add a condition to verify a field is not the same as the previous field in the table (if one exists), so I try this code I found online (and it works fine when I try it with test data)...
AND vend_id <> NVL((SELECT vend_id FROM (SELECT c.*, ROWNUM rnum FROM (SELECT * FROM table1
WHERE acct_num=x.acct_num
AND trans_dt<x.trans_dt
ORDER BY trans_dt DESC) c
WHERE ROWNUM<=2)
WHERE rnum>=2)
,'XXX')but when I try to run it in the update query, I get an error, "x.trans_dt" invalid identifier. This is just another condition to what was posted in the first code block and Oracle "sees" all the x.* values there fine.
Can anyone tell me what is wrong here and how I can pass these values into this condition?
Thanks!<tt>x.trans_dt</tt> and <tt>x.trans_dt</tt> are just nested too deeply (can only be on next level)
AND vend_id <> NVL((SELECT vend_id
FROM (SELECT c.*, ROWNUM rnum
FROM (SELECT *
FROM table1
WHERE acct_num = x.acct_num
AND trans_dt < x.trans_dt
ORDER BY trans_dt DESC
) c
WHERE ROWNUM <= 2
WHERE rnum >= 2
'XXX'
)use <tt>merge</tt> to do the update
Regards
Etbin -
How to use group function in insert or update
Hai All
How can we use group function in insert or update statement
I am generating an attendance so i have different set of timing for example
0800,1200,1230, 1700 and i need to insert into these data into table with min value to intime and max value to
outtime and othere to inertval time in or out
Pls tell me with some example
For example
For INSERT
insert into T2 (barcode,empcode,intime,attend_date)
values(r2.cardn,r2.enpno,MIN(r2.ptime),r2.pdate);
For UPDATE
update dail_att set outtime= MAX(r2.ptime) where empcode=r2.enpno and barcode=r2.cardn and
attend_date=r2.pdate;
Here instead of where i need to use having so pls tell how to use
Thanks & Regards
Srikkanth.MHai Man
R2 is not a table name its a record
Let me explain clearly
I have to generate daily attendance for lot of employees So i have two table t1 and t2
T1 consist of three column empno,date,time
T2 consist of empno,name,date,intime,outtime,intrin,introut
So now i need to give the T1 Min value Of time to T2 Intime and T1 Max value of Time to T2 Outtime fields so there so many records while i am using
max(time) it gives the max value of all so i seperated by group function so now i have an error in subquery ie it is an single row subquery so i need to use multiple row subquery how i can use multiple row subquery in update statement
Thanks In Advance
Srikkanth.M -
UPDATE involving the same table in sub query
DB version: 11.2
We have a table called SHP_GC_TRACK which has around 8 million records with partitions . In the below UPDATE, it is updating a column based on the SELECT on the same table in a subquery.
UPDATE shp_gc_track a
SET f_tran_proc = 'Y'
WHERE last_update_date <
(SELECT MAX (last_update_date)
FROM shp_gc_track b
WHERE a.shp_trx_rowid = b.shp_trx_rowid
AND a.c_shp_inst = b.c_shp_inst
AND a.f_tran_proc = b.f_tran_proc
AND b.f_ltr_received = 'D'
AND f_rec_code IN ('G', 'W')
AND b.f_rec_status = 'B'
AND b.c_shp_inst = :b1
AND a.c_shp_inst = :b1
AND a.f_ltr_received = 'D' -----------------> part of composite index
AND a.f_tran_proc = 'N' -----------------> part of composite index
AND a.f_rec_code IN ('G', 'W') --------------> part of composite index
AND a.f_rec_status = 'B'; -----------------> part of composite index This UPDATE takes a long time to execute and sometime get hung.
We have a composite index on four columns f_ltr_received, f_rec_code, f_rec_status, f_tran_proc . Explain plan shows this composite index is being used.
Is there anyway to rewrite this query or any other suggestions ?Steve_74 wrote:
DB version: 11.2
We have a table called SHP_GC_TRACK which has around 8 million records with partitions . In the below UPDATE, it is updating a column based on the SELECT on the same table in a subquery.
UPDATE shp_gc_track a
SET f_tran_proc = 'Y'
WHERE last_update_date <
(SELECT MAX (last_update_date)
FROM shp_gc_track b
WHERE a.shp_trx_rowid = b.shp_trx_rowid
AND a.c_shp_inst = b.c_shp_inst
AND a.f_tran_proc = b.f_tran_proc
AND b.f_ltr_received = 'D'
AND f_rec_code IN ('G', 'W')
AND b.f_rec_status = 'B'
AND b.c_shp_inst = :b1
AND a.c_shp_inst = :b1
AND a.f_ltr_received = 'D' -----------------> part of composite index
AND a.f_tran_proc = 'N' -----------------> part of composite index
AND a.f_rec_code IN ('G', 'W') --------------> part of composite index
AND a.f_rec_status = 'B'; -----------------> part of composite index This UPDATE takes a long time to execute and sometime get hung.
We have a composite index on four columns f_ltr_received, f_rec_code, f_rec_status, f_tran_proc . Explain plan shows this composite index is being used.
Is there anyway to rewrite this query or any other suggestions ?Tuning updates with subqueries can be hard :(. Sadly my suggestions below are of the try-it-and-see-what-happens variety - nothing certain
First, check the index. Is it bitmap or b-tree? If b-tree see if the most restrictive columns are listed first - this can help with b-tree index efficiency. Also if b-tree a composite bitmap for columns with lots of repeating values instead might help
Its a correlated subquery so you can't just run the subquery first putting the result into a scalar varaiable and using the variable in the SQL instead. You can try putting the results of the subuqery w/join keys in a GTT first using the GTT in the SQL to see if I/O is reduced overall during both operations.
Do you have the licence for the parallel query option? Using parallel DML (this must be turned on manually) might help. Check the docs for the ALTER SESSION command to do this. Also, the PARALLEL_INDEX() hint might help
Post the execution plan of the SQL -
Why update with subqueries does not have cost and cardinality?
There is update.
update test t1 set dummy = (select dummy from test2 t2 where t1.id = t2.id);Both tables which have actual statistics. Each has 1000 rows. And column ID have values from 1 to 1000 in each table.
This is explain plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | UPDATE STATEMENT | | 1000 | 13000 | 426 (9)| 00:00:01 |
| 1 | UPDATE | TEST | | | | |
| 2 | TABLE ACCESS FULL| TEST | 1000 | 13000 | 426 (9)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| TEST2 | 1 | 13 | 426 (9)| 00:00:01 |
Predicate Information (identified by operation id):
3 - filter("T2"."ID"=:B1)We can see here, that Oracle consider subquery within update as once-executed subquery.
This is runtime plan
| Id | Operation | Name | Starts | E-Rows | A-Rows |
| 1 | UPDATE | TEST | 1 | | 0 |
| 2 | TABLE ACCESS FULL| TEST | 1 | 1000 | 1000 |
|* 3 | TABLE ACCESS FULL| TEST2 | 1000 | 1 | 1000 |
Predicate Information (identified by operation id):
3 - filter("T2"."ID"=:B1)Why first plan does not have cost in step 1?
Does Oracle always not understand that update with subqueries will performed as NL or filter? In other words that step 3 will executed many times.
Or it is my bug (or what?)?793769 wrote:
Does Oracle always not understand that update with subqueries will performed as NL or filter? In other words that step 3 will executed many times.
Or it is my bug (or what?)?It's not possible to say whether this is a bug or a deliberate choice.
Because of "subquery caching" (see http://jonathanlewis.wordpress.com/2006/11/06/filter-subqueries/ ) the optimizer cannot predict how often the subquery will have to run. So possibly it shows nothing rather than showing the best or worst cases or a pure guess.
Regards
Jonathan Lewis -
Update statement with EXISTS clause
I saw this code in one of the procedures we are using ... is it possible to avoid EXIST caluse:
update table_x p
set p.internal_issue_ky = (select sh.internal_issue_ky
from security_history sh, XT_SECURITY xs
where sh.internal_wins_issue_id = xs.internal_wins_issue_id
and sh.as_of_dt = xs.as_of_date
and p.internal_wins_issue_id = sh.internal_wins_issue_id
and p.effective_dt between sh.as_of_dt and sh.next_as_of_dt
where exists
(select sh.internal_issue_ky
from security_history sh, XT_SECURITY xs
where sh.internal_wins_issue_id = xs.internal_wins_issue_id
and sh.as_of_dt = xs.as_of_date
and p.internal_wins_issue_id = sh.internal_wins_issue_id
and p.effective_dt between sh.as_of_dt and sh.next_as_of_dt
Thanks.Without the EXISTS, every record in the table will be updated, and those that don't exist in the subquery will be updated with NULL. The EXIST clause ensures that only those records that form the subset in the subquery are updated, and is necessary here.
-
Updation of hz_cust-acct_sites_all
hi friends
when i update ship_to_flag i got some error can any one help me this
update hz_cust_acct_sites_all
set SHIP_to_flag='P'
where ORIG_SYSTEM_REFERENCE = (SELECT CUST_ACCT_SITE_ID FROM HZ_CUST_ACCT_SITES_ALL);
thanksHello
You need to clarify what you want to do. As Srikkanth noted, you are using = which expects 1 value, with the query
SELECT CUST_ACCT_SITE_ID FROM HZ_CUST_ACCT_SITES_ALLwhich will return multiple values.
So you either need to update your query to
update hz_cust_acct_sites_all
set SHIP_to_flag='P'
where ORIG_SYSTEM_REFERENCE IN (SELECT CUST_ACCT_SITE_ID FROM HZ_CUST_ACCT_SITES_ALL);or, depending on your requirement, you might be able to get rid of the subquery alltogether -
update hz_cust_acct_sites_all
set SHIP_to_flag='P'
where ORIG_SYSTEM_REFERENCE = CUST_ACCT_SITE_ID but that depends heavily on how your data is structured and what you are trying to achieve.
David -
Updating a table using subquery
Hi,
I need to update a column of test1 table with the values of test2 table
joining both tables by the code
update test1 t1 set t1.column1 = (select t2.column2 from test2 t2 where t2.column3 = 'somevalue')
where t1.code = t2.codethe code that I describe below doesnt works and give me the next error:
Error SQL: ORA-00904: "t2.code": invalid identifierwhats wrong??
thanks in advancedHi,
The outer query (the update) doesn't "see" t2 as it is in the inner query (the select).
You can either update the join directly :update (
select t1.column1 col1, t2.column2 col2
from test1 t1
left join test2 t2
on (t1.code=t2.code)
and t2.column3='somevalue'
) v
set col1=col2;or use merge operation, or add the where clause and use correlated subquery as in :update test1 t1 set t1.column1 = (select t2.column2 from test2 t2 where t2.code = t1.code and t2.column3 = 'somevalue')
where exists (select null from test2 t2 where t2.code = t1.code and t2.column3 = 'somevalue'); -
Update column with subquery returning more than one row
Hi Everybody,
Please let me know how to handle this. I am writing update statement in procedure with subquery and it is returning multiple rows. Please help me, how i can handle this :
UPDATE TABLEA A
SET A.ERROR_MESSAGE = (Select B.XERROR_MESSAGE from TABLEB B, TABLEA A WHERE B.id = A.id)
WHERE A.id = (Select B.id from TABLEB B, TABLEA A WHERE B.id = A.id);
(Select B.XERROR_MESSAGE from TABLEB B, TABLEA A WHERE B.id = A.id) --- This subquery is returning more than one rows. How i can handle this in Pl/SQL?
Please let me know. I will be very thankful to you all.
I will really appreciate your replies and comments.
Thank youTry getting rid of tablea in your subqueries. You already have it in the UPDATE statement.
UPDATE TABLEA A
SET A.ERROR_MESSAGE = (Select B.XERROR_MESSAGE
from TABLEB B
WHERE B.id = A.id
WHERE A.id = (Select B.id
from TABLEB B
WHERE B.id = A.id);You can also try a simple MERGE:
merge into tablea a
using tableb b
on (a.id = b.id)
when matched then update
set a.error_message = b.xerror_message; -
I'd like to update all the rows with values getting from subquery from the same table.
For example, the subquery of
select id, some_manipulation as value from table_a
id value
1 12
2 14
3 16
4 21
I'd like to use above info update the values of a column (column2 of table_a) according to the same id. Something like this
update table_a a
set a.column2 = b.value
where a.id =
(select b.id from table_a b);
I know above sql sytax is invalid, but I just want to give you an idea what I'm tryig to accomplish. Any idea?
Thanks in advance,
IttichaiA slightly modified version of Sri's solution will work for all cases. Assuming proper indexing, this should be relatively fast.
SQL>SELECT * FROM table_a;
ID COL1 COL2
1 2 0
2 3 0
3 1 15
SQL>SELECT * FROM table_b;
ID COLA
1 6
2 12
SQL>UPDATE table_a a
2 SET col2 = nvl((SELECT a.col1*b.cola
3 FROM table_b b
4 WHERE a.id = b.id),a.col2);
3 rows updated.
SQL>commit;
Commit complete.
SQL>SELECT * FROM table_a;
ID COL1 COL2
1 2 12
2 3 36
3 1 15In the case of table_b not having the id, the current value of col2 will be retained. If you want some other value, then substitute it in the NVL. You can even use a different select statement as the return from nvl.
SQL>UPDATE table_a a
2 SET col2 = nvl((SELECT a.col1*b.cola
3 FROM table_b b
4 WHERE a.id = b.id),(SELECT col2 from table_a where id = 2));
3 rows updated.
SQL>commit;
Commit complete.
SQL>SELECT * FROM table_a;
ID COL1 COL2
1 2 12
2 3 36
3 1 36 -
Update query running fine when subquery in where clause is wrong.
Hi,
I am running one update statement-
Update table a set column1=2000
where a.column2 in(select col 3 from Table b where b.col4=111)
Now when I run the subquery: select col 3 from Table b where b.col4=111-----> It gives me error "col 3 invalid identifier"
But when I run the full query then it updates the 700 rows.
Can somebody please explain this?
My subquery is throwing error but when i use that in another query it is running fine.Col_3 must be in your outer table (table_a, I guess).
If you always prefixed column names with a table alias, you'd know in an instant. -
Update with subquery in TopLink ?
I want to activate the user account updating its status to ACTIVE.
UPDATE PujUserEntity as user SET user.status.id = (SELECT status.id from PujUserStatusEntity status WHERE status.tag='ACTIVE') WHERE user.login= :login AND user.email= :email
the error during the deployment on Glassfish (TopLink):
CLI171 Command deploy failed : Deploying application in domain failed;
Exception Description: Syntax error parsing the query [activateUserAccount: UPDATE PujUserEntity as user SET user.status.id = (SELECT status.id from PujUserStatusEntity status WHERE status.tag='ACTIVE') WHERE user.login= :userLogin AND user.email= :userEmail], line 1, column 52: unexpected token [SELECT].
Internal Exception: line 1:52: unexpected token: SELECTAccording to JPA specification you are not allowed to use subquery in that place. In SET part you can only use simple_arithmetic_expression | string_primary | datetime_primary | boolean_primary | enum_primary | simple_entity_expression | NULL (JSR 220 Java Persistence API specification page 104). You should be able to use native query, or find status.id first and then just pass it as parameter.
-
Update with exists and subquery
Hi how to pass index to this sql
Table pap ( eqid,seq,histseq,docno,status,value1,value2)
PK(eqid,seq,histseq) and indx (docno)
table pa ( eqid,seq,docno,status,value1,value2)
PK(eqid,seq) and indx (docno)
update pa
set (value1,value2) = (select pap.value1,pap.value2 from pap
where pap.eqid = pa.eqid
and pap.seq = pa.seq
and pap.histseq =1
and pap.docno <> pa.docno
and pap.status = 4 )
where pa.status=1
and exists ( select 1 from pap
where pap.eqid = pa.eqid
and pap.seq = pa.seq
and pap.histseq =1
and pap.docno <> pa.docno
and pap.status =4 )
It is doing fulltable scan on pa and using hash join .
How to write update with subquery method also ?There's nothing wrong with a full scan.
Please read this explanation/example: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:9422487749968
If you want more explanation then please follow these guidelines below, so we have sufficient inputs:
[When your query takes too long...|http://forums.oracle.com/forums/thread.jspa?messageID=1812597#1812597]
[How to post a SQL statement tuning request|http://forums.oracle.com/forums/thread.jspa?threadID=863295&tstart=0]
Remember to put the tag befor and after the examples you post.
See http://forums.oracle.com/forums/help.jspa regarding tags. -
I have 2 tables
tblA(aID, aSeq, aname, aLname)
tblB(bSeq, bname, bLname)
I need to update table tblA to set aSeq where the name and Lname match with tblB. Something like
update zA A
set A.aSeq =
select B.bSeq
from zB B
where UPPER(B.bname) = UPPER(A.aname)
and UPPER(B.blname) = UPPER(A.alname)
What am I doing wrong? Why do I get the error - ORA-01427: single-row subquery returns more than one rowbased on above scenario (tblA => proposal tblB => personnel)
select rp.prop_id || '| ' || UPPER(rp.prodir_fn) || '| ' || UPPER(rp.prodir_ln)
from proposal rp
where exists(
select p.piid ---------------------------------------------------get matching names from personnel
from personnel p
where UPPER(rp.prodir_fn) = UPPER(p.fname)
and UPPER(rp.prodir_ln) = UPPER(p.lname)
and EXISTS
( select UPPER(q.fname), UPPER(q.lname) ------------ get matching names of single person that is drop
from personnel q--------------------------------------------- peron names who have same first and last name different id
where UPPER(q.fname) = UPPER(p.fname)
and UPPER(q.lname) = UPPER(p.lname)
group by UPPER(q.fname), UPPER(q.lname)
having count(*) = 1
gives me 3535 matching records
but
my update still fails, Please guide
UPDATE proposal rp
set rp.pi = (
select p.piid
from personnel p
where UPPER(rp.prodir_fn) = UPPER(p.fname)
and UPPER(rp.prodir_ln) = UPPER(p.lname)
and EXISTS
( select UPPER(q.fname), UPPER(q.lname)
from personnel q
where UPPER(q.fname) = UPPER(p.fname)
and UPPER(q.lname) = UPPER(p.lname)
group by UPPER(q.fname), UPPER(q.lname)
having count(*) = 1
;
Maybe you are looking for
-
802.11b vs 802.11a & g
Hi there, any one can give me some idea on the best practise about the choosing the WLAN 802.11 protocols. I know that the in WLAN network, all device shares the same access point in half duplex, so using 11g, it would give us 45mbps to share than
-
Review my billing information everytime I sign in
Created an Apple ID, log into the Apple website just fine. Try logging into the iTunes store, and I'll get an iTunes pop up that says, "This Apple ID has not yet been used with the iTunes Store. Please review your account information." Well, I've re
-
I'm looking to find a developers version download of ColdFusion 8 and 9. The links I've found on the web are now all redirecting to the download page for CF10. Are these still available? The CF 8 and 9 exams are so you'd think the dev versions would
-
Master image not available?
after downloading my pics from a sd card, my photos sow that master image is not available. can someone help? i am a new mom and all the pictures are of my son. i have deleted them from the sd card. I am not fmiliar with aperture so sorry if this is
-
When I shut down my computer and restart and try to use dashboard it just come up with a plus sign on the bottom left and all the one i had disappeared. When i try to add new one dashboard just crash(not really crashed) it just close...