oracle sql update based on subquery between two tables

3
Take the 2-minute tour × I am currently writing update statements to keep a query-able table constantly up to date. The schema is identical between both tables and the contents are not important: STAGING ID NAME COUNT PRODUCTION ID NAME COUNT My update statement looks as follows: update PRODUCTION set name = ( select stage . name from staging stage where stage . name = name and rownum count = ( select stage . countfrom staging stage where stage . count = count and r The two things of note is that 1) There is no where clause at the end of my update (this may be the problem) and 2) all records after being updated have the same values. What I mean by this is the following: BEFORE UPDATE : 1 , "JOHN" , 12 ; 2 , "STEVE" , 15 ; 3 , "BETTY" , 2 ; AFTER UPDATE 1 , "JOHN" , 12 ; 2 , "JOHN" , 12 ; 3 , "JOHN" , 12 ; My question is how do I fix this so that the table properly reflects "new" data from staging as a correct SQL update? UPDATE So my staging data could coincidentally mirror what is in PRODUCTION and for the sake of discussion it will: STAGING DATA TO MERGE : 1 , "JOHN" , 12 ; 2 , "STEVE" , 15 ; 3 , "BETTY" , 2 ; Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required. Oracle SQL update based on subquery between two tables sign up log in tour help careers 2.0

Upload: kashifmeo

Post on 25-Apr-2017

220 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Oracle SQL Update Based on Subquery Between Two Tables

Take the 2-minute tour ×

I am currently writing update statements to keep a query-able table constantly up to date. The schema isidentical between both tables and the contents are not important:

STAGING

ID NAME COUNT

PRODUCTION

ID NAME COUNT

My update statement looks as follows:

update PRODUCTION set name = (select stage.name from staging stage where stage.name=name and rownum <2), count = (select stage.countfrom staging stage where stage.count=count and rownum <2);

The two things of note is that 1) There is no where clause at the end of my update (this may be theproblem) and 2) all records after being updated have the same values. What I mean by this is thefollowing:

BEFORE UPDATE:

1,"JOHN", 12; 2,"STEVE",15; 3,"BETTY",2;

AFTER UPDATE

1,"JOHN", 12; 2,"JOHN",12; 3,"JOHN",12;

My question is how do I fix this so that the table properly reflects "new" data from staging as a correctSQL update?

UPDATE

So my staging data could coincidentally mirror what is in PRODUCTION and for the sake of discussion itwill:

STAGING DATA TO MERGE:

1,"JOHN", 12; 2,"STEVE",15; 3,"BETTY",2;

Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, noregistration required.

Oracle SQL update based on subquery between two tables

sign up

log in

tour

help

careers 2.0

Page 2: Oracle SQL Update Based on Subquery Between Two Tables

Woot4Moo

13.9k 6 30 72

3 Answers

Conrad Frix

33.2k 7 30 65

3,"BETTY",2;

UPDATE the second

The query that I would like to run would be this:

update PRODUCTIONset production.name = staging.name, production.count = staging.count

where production.name = staging.name;

This however results in invalid identifier issues on "staging.name"

sql oracle

edited Jul 27 '12 at 17:55 asked Jul 27 '12 at 17:33

Do you want to keep name and count in PRODUCTION table up-to date and STAGING table is changing? –

hmmftg Jul 27 '12 at 17:39

Why don't you use triggers to insert new values instead of this update? what does this update exactly do? –

hmmftg Jul 27 '12 at 17:42

Agreed, when syncing tables, triggers can be really useful in keeping them up to date real time. Just watch

out for mutating table errors, and be sure to do it as an AFTER INSERT OR UPDATE. – Hermit Jul 27 '12 at

17:45

@hmmftg This update is just to pull data in from staging to keep production up to date. Similar to how weather

reports get updated for a real life example. Every X minutes or so – Woot4Moo Jul 27 '12 at 17:49

@Hermit This most likely will become a trigger, I am testing out the plain sql by itself. – Woot4Moo Jul 27

'12 at 17:51

There are two ways to do what you are trying

One is a Multi-column Correlated Update

UPDATE PRODUCTION aSET (name, count) = ( SELECT name, count FROM STAGING b WHERE a.ID = b.ID);

DEMO

You can use merge

MERGE INTO PRODUCTION aUSING ( select id, name, count from STAGING ) bON ( a.id = b.id )WHEN MATCHED THEN UPDATE SET a.name = b.name, a.count = b.count

DEMO

answered Jul 27 '12 at 18:33

Let me try the multi-column correlated. I had to move away from merge because of it being slow (over 10

million records) – Woot4Moo Jul 27 '12 at 18:35

add comment

add comment

Page 3: Oracle SQL Update Based on Subquery Between Two Tables

Hermit

127 2

khoxsey

1,092 3 10

Without examples of the dataset of staging this is a shot in the dark, but have you tried something likethis?

update PRODUCTION p, staging sset p.name = s.name p.count = s.countwhere p.id = s.id

This would work assuming the id column matches on both tables.

answered Jul 27 '12 at 17:44

So what if the only things that I want to match on are the where clauses in my subqueries? IE set blah where

p.name=s.name and p.count=s.count? – Woot4Moo Jul 27 '12 at 17:50

If you did that, you would be setting a = to b where a is = to b (i.e. it would do nothing). – Hermit Jul 27 '12 at

18:09

Oops failed logic on my part :) – Woot4Moo Jul 27 '12 at 18:19

This won't work on oracle see here – Conrad Frix Jul 27 '12 at 18:34

As you've noticed, you have no selectivity to your update statement so it is updating your entire table. Ifyou want to update specific rows (ie where the IDs match) you probably want to do a coordinatedsubquery.

However, since you are using Oracle, it might be easier to create a materialized view for your query tableand let Oracle's transaction mechanism handle the details. MVs work exactly like a table for queryingsemantics, are quite easy to set up, and allow you to specify the refresh interval.

answered Jul 27 '12 at 17:42

Not the answer you're looking for? Browse other questions tagged sql oracle or ask

your own question.

add comment

add comment