Combine update statement and select statement - sql

I'm using Oracle SQL Developer and I'm trying combine an update and a select statment into one. I know that Oracle dosen't support FROM or JOINS directly in the update statement and I therefor put the select in a subquery but it still don't work.
I have got two tables; MASTERTABLE and TESTTABLE.
MASTERTABLE contain an ID_NUMBER column and a TESTTABLE_ID column.
TESTTABLE contains a TESTTABLE_ID column and a TEST_COLUMN column.
What I want to do is to update the TEST_COLUMN value while only knowing the ID_NUMBER.
What my statement looks like:
UPDATE TESTTABLE
SET TEST_COLUMN= 'Testvalue'
WHERE TESTTABLE.TESTTABLE_ID IN (SELECT MASTERTABLE.TESTTABLE_ID
FROM MASTERTABLE
WHERE ID_NUMBER=11);
But I get stuck in some kind of loop. Where did I go wrong?

I have faced the same problem. The solution is usage of MERGE operation instead of UPDATE.
MERGE INTO TESTTABLE t
USING
(
SELECT m.ID_NUMBER num,
m.TESTTABLE_ID id
FROM MASTERTABLE m
) newnum ON (t.TESTTABLE_ID = newnum.id)
WHEN MATCHED THEN UPDATE
SET t.TEST_COLUMN = newnum.num;

You can try any one of this in Oracle
Normal Update
UPDATE
TESTTABLE
SET
TEST_COLUMN= 'Testvalue'
WHERE
EXISTS
(SELECT MASTERTABLE.TESTTABLE_ID
FROM MASTERTABLE
WHERE ID_NUMBER=11);
Using Inline View (If it is considered updateable by Oracle)
Note: If you face a non key preserved row error add an index to resolve the same to make it update-able
UPDATE
(SELECT
TESTTABLE.TEST_COLUMN AS OLD,
'Testvalue' AS NEW
FROM
TESTTABLE
INNER JOIN
MASTERTABLE
ON TESTTABLE.TESTTABLE_ID = MASTERTABLE.TESTTABLE_ID
WHERE ID_NUMBER=11) T
SET
T.OLD = T.NEW;
Using Merge
MERGE INTO
TESTTABLE
USING
(SELECT
T1.ROWID AS RID,
T2.TESTTABLE_ID
FROM
TESTTABLE T1
INNER JOIN
MASTERTABLE T2
ON TESTTABLE.TESTTABLE_ID = MASTERTABLE.TESTTABLE_ID
WHERE ID_NUMBER=11)
ON
( ROWID = RID )
WHEN MATCHED
THEN
UPDATE SET TEST_COLUMN= 'Testvalue';

The problem was as Tom H wrote a blocking problem. When I started working on the project today all of the solutions worked.

Related

update tbl_1 set tbl_1.valueA = tbl2.valueB when tbl_2.valueC is equal to tbl_1valueD

As the title indicates - I'm trying to update a table.value with another table.value based on a common value in the 2 tables (but not same column names)
First I delete any duplicate records in the source table.
And count the remaining rows - that total is 93.
Select rowid, xfmid_value from w_valve_reftest;
Delete from w_valve_reftest a
where rowid> (select min(rowid)
from w_valve_reftest b where b.xfmid_value=a.XFMID_VALUE);
Select count(*) from w_valve_reftest;
Next I want to update the target.reference_1 with the value from source.ref1_value and target.reference_2 with source.ref2_value where source.xfmid_value=target.xfm_id
Here is what I have, but for some reason it is updating 17,000+ records. Rather than the 93 I expect.
update w_isolationvalve
set w_isolationvalve.reference_1=(select ref1_value from w_valve_reftest where w_isolationvalve.xfm_id=w_valve_reftest.xfmid_value);
update W_isolationvalve
set w_isolationvalve.reference_2=(select ref2_value from w_valve_reftest where w_isolationvalve.xfm_id=w_valve_reftest.xfmid_value);
I'm no expert, but not a rookie any longer. I've hacked it this far using google. Thanks for any assist.
Your second query should be:
update a
set reference_1=b.ref1_value,
refrence_2=b.ref2_value
FROM w_isolationvalve a
JOIN w_valve_reftest b ON a.xfm_id=b.xfmid_value
As for the update counts, it will only be 93 only if xfm_id and xfmid_value are unique.
Also be careful of non-deterministic updates.
If your select will have multiple results for your join condition, the update will be executed once for each of the multiple results and you will not know what you end up with.
This should work in Oracle:
MERGE INTO w_isolationvalve a
USING
(
SELECT * FROM w_valve_reftest
)b
ON(a.xfm_id = b.xfmid_value)
WHEN MATCHED THEN UPDATE SET
a.reference_1 = b.ref1_value,
a.refrence_2 = b.ref2_value ;
Since you do not like merge. I think this should also work in Oracle:
UPDATE
(SELECT a.reference_1, a.refrence_2, b.ref1_value , b.ref2_value
FROM w_isolationvalve a
INNER JOIN w_valve_reftest b
ON a.xfm_id = b.xfmid_value
) t
SET t.reference_1 = t.ref1_value ,
t.refrence_2 =t.ref2_value

updating sql query value with select statement

I am trying to execute a query which is something like:
update table set column=(select column1 from table1);
I just want to store the value from other table to my column
but when i try my sql query it says
ERROR 1242 (21000): Subquery returns more than 1 row
definitely this means my table1 contains more than 1 row so i want to know that is there any way to store data into column from other table with multiple row.
or basically saving content of other table as a text something like
update table set column='Data in text from other table';
You probably need a correlation clause:
update table
set column = (select column1 from table1 where table.col = table1.col);
You need to decide what column(s) are used for the correlation.
it will work as i am getting your requirement.Please let me know if your requirement is other i ll make changes in query
update table_name t1
inner join table1 t2 on t1.id =t2.id
set column =column1
Your nested query returns multiple rows so you encountered this error.
Try in this way
UPDATE FirstTable
SET FirstTable.ColumnName =tbl2.ColumnName
FROM SecondTable tbl2 WHERE tbl2.Id = FirstTable.Id
There should be a common id or something that will help to find exact row.

Using Ids from temp table to update actual table

I am selecting two values into a temp table.
After I have done this, I want to do an update, to one of the tables I select from, on all the Id's that I just selected into my temp table.
How do I do this?
It sounds pretty simple I just can't really figure out where to begin.
I tried
update table set value = #tempTable.value where id = #temptable.id
but of course that didn't work.
I can, of course, do a select that gives me the update commands, for each entry in the temp table, but I would very much like to do this, in one process instead of having to execute the update commands afterwards.
Do I need to make some foreach from the temp table?
Try this way:
update tab
set value = tt.value
from #temptable tt
where tab.id = tt.id
Try this one -
UPDATE t
SET value = t2.value
FROM [table] t
JOIN #temptable t2 ON t.id = t2.id

Create table from SQL query

This is one annoying issue and I can't figure out how to solve it. I'm Using Microsoft SQL Server 2008.
So I have two tables and I need to update both of them. They share a common key, say id. I want to update Table1 with some stuff and then update the Table2 rows which were respectively modified in Table1.
The issue is that I don't quite know which rows were modified, because I'm picking them randomly with ORDER BY NEWID() so I probably cannot use a JOIN on Table2 in any way. I am trying to save the necessary details which were modified in my query for Table1 and pass them to Table2
This is what I'm trying to do
CREATE TABLE IDS (id int not null, secondid int)
SELECT [Table1].[id], [Table1].[secondid]
INTO IDS
FROM
(
UPDATE [Table1]
SET [secondid]=100
FROM [Table1] t
WHERE t.[id] IN
(SELECT TOP 100 PERCENT t.[id] FROM [Table1]
WHERE (SOME_CONDITION)
ORDER BY NEWID()
)
)
UPDATE [Table2]
SET some_column=i.secondid
FROM [Table2] JOIN IDS i ON i.id = [Table2].[id]
But I get
Incorrect syntax near the keyword 'UPDATE'.
So the question is: how can I solve the syntax error or is it a better way to do this?
Note: the query enclosed between the parentheses of the first FROM worked well before this new requirement, so I doubt there's a problem in there. Or maybe?
EDIT: Changing the second UPDATE as skk suggested still leads to the same error (on exactly the below line which contains UPDATE):
UPDATE [Table2]
SET some_column=i.secondid
FROM [Task] JOIN IDS i on i.[id]=[Table2].[id]
WHERE i.id=some_value
Instead of creating a new table manually, SQL server has the OUTPUT clause to help with this
It's complaining because you aren't aliasing the derived table used in the first query, immediately preceding UPDATE [Table2].
If you add an alias, you'll get a different error:
A nested INSERT, UPDATE, DELETE, or MERGE statement must have an OUTPUT clause.
Which leads back to #Adam Wenger's answer.
Not sure I completely understand what you are trying to do, but the following sql will execute (after replacing SOME_CONDITION):
CREATE TABLE IDS (id int not null, secondid int)
UPDATE t SET [secondid] = 100
OUTPUT inserted.[id], inserted.[secondid] into [IDS]
FROM [Table1] t
WHERE t.[Id] IN
(
SELECT TOP 100 PERCENT t.[id] from [Table1]
WHERE (SOME_CONDITION)
ORDER BY NEWID()
)
UPDATE [Table2]
SET some_column = i.secondid
FROM [Table2] JOIN IDS i ON i.id = [Table2].[id]
The Update syntax is as follows
UPDATE TableName SET ColumnName = Value WHERE {Condition}
but you have used FROM keyword also in that.
EDIT:
You change the code like follows and try again
UPDATE [Table2] SET some_column=IDS.secondid WHERE IDS.[id] = [Table2].[id] and
IDS.id=some_value

Update multiple columns in a TABLE from another TABLE (Oracle)

I would like to update multiple columns in one table based on values in another.
I think I know how to write an update statement in T-SQL that does what I want (haven't tested the below). Problem is I'm trying to translate this for an Oracle database. Does anyone know how to do the following in Oracle:
UPDATE oldauth SET
AUTHUNIQUENAME=newauth.AUTHUNIQUENAME
DESCRIPTION=newauth.DESCRIPTION
MAPPINGAUTHNAME=newauth.MAPPINGAUTHNAME
FROM
(SELECT * FROM USERS1 WHERE AUTHSOURCEID=100) oldauth
LEFT JOIN
(SELECT * FROM USERS2 WHERE AUTHSOURCEID=200) newauth
ON
oldauth.AUTHUSERNAME=newauth.AUTHUSERNAME;
MERGE
INTO (
SELECT *
FROM users1
WHERE AUTHSOURCEID=100
) oldauth
USING (
SELECT *
FROM users2
WHERE AUTHSOURCEID=200
) newauth
ON oldauth.AUTHUSERNAME=newauth.AUTHUSERNAME
WHEN MATCHED THEN
UPDATE
SET AUTHUNIQUENAME=newauth.AUTHUNIQUENAME,
DESCRIPTION=newauth.DESCRIPTION,
MAPPINGAUTHNAME=newauth.MAPPINGAUTHNAME