What is wrong with my update statement with a join in Oracle?
Good question.
To simulate your situation, I've created sample tables:
SQL> create table t_debtor(id_debtor,header)
2 as
3 select 1, 'Header 1' from dual union all
4 select 2, null from dual union all
5 select 3, 'Header 3' from dual
6 /
Tabel is aangemaakt.
SQL> create table t_element (id_element,id_debtor,insurer)
2 as
3 select 1, 1, 'to be updated' from dual union all
4 select 2, 1, 'to be updated' from dual union all
5 select 3, 2, 'not to be updated' from dual union all
6 select 4, 2, 'not to be updated' from dual union all
7 select 5, 3, 'to be updated' from dual
8 /
Tabel is aangemaakt.
And with your current update statement, the problem becomes clear: the "not to be updated" values are set to NULL:
SQL> update
2 T_ELEMENT elt
3 set elt.INSURER = (
4 select HEADER
5 from T_DEBTOR debtor
6 where
7 debtor.HEADER is not null
8 and debtor.ID_DEBTOR = elt.ID_DEBTOR)
9 /
5 rijen zijn bijgewerkt.
SQL> select * from t_element
2 /
ID_ELEMENT ID_DEBTOR INSURER
---------- ---------- -----------------
1 1 Header 1
2 1 Header 1
3 2
4 2
5 3 Header 3
5 rijen zijn geselecteerd.
The best way to do this update, is to update a join of both tables. There are some restrictions however:
SQL> rollback
2 /
Rollback is voltooid.
SQL> update ( select elt.insurer
2 , dtr.header
3 from t_element elt
4 , t_debtor dtr
5 where elt.id_debtor = dtr.id_debtor
6 and dtr.header is not null
7 )
8 set insurer = header
9 /
set insurer = header
*
FOUT in regel 8:
.ORA-01779: cannot modify a column which maps to a non key-preserved table
With the bypass ujvc hint, we can circumvent this restriction.
But it is not advisable to do so unless you know really really sure that t_debtor.id_debtor is unique.
SQL> update /*+ bypass_ujvc */
2 ( select elt.insurer
3 , dtr.header
4 from t_element elt
5 , t_debtor dtr
6 where elt.id_debtor = dtr.id_debtor
7 and dtr.header is not null
8 )
9 set insurer = header
10 /
3 rijen zijn bijgewerkt.
SQL> select * from t_element
2 /
ID_ELEMENT ID_DEBTOR INSURER
---------- ---------- -----------------
1 1 Header 1
2 1 Header 1
3 2 not to be updated
4 2 not to be updated
5 3 Header 3
5 rijen zijn geselecteerd.
It's better to just add a primary key. You'll probably have this one already in place:
SQL> rollback
2 /
Rollback is voltooid.
SQL> alter table t_debtor add primary key (id_debtor)
2 /
Tabel is gewijzigd.
SQL> update ( select elt.insurer
2 , dtr.header
3 from t_element elt
4 , t_debtor dtr
5 where elt.id_debtor = dtr.id_debtor
6 and dtr.header is not null
7 )
8 set insurer = header
9 /
3 rijen zijn bijgewerkt.
SQL> select * from t_element
2 /
ID_ELEMENT ID_DEBTOR INSURER
---------- ---------- -----------------
1 1 Header 1
2 1 Header 1
3 2 not to be updated
4 2 not to be updated
5 3 Header 3
5 rijen zijn geselecteerd.
Regards,
Rob.
Update statement with inner join on Oracle
That syntax isn't valid in Oracle. You can do this:
UPDATE table1 SET table1.value = (SELECT table2.CODE
FROM table2
WHERE table1.value = table2.DESC)
WHERE table1.UPDATETYPE='blah'
AND EXISTS (SELECT table2.CODE
FROM table2
WHERE table1.value = table2.DESC);
Or you might be able to do this:
UPDATE
(SELECT table1.value as OLD, table2.CODE as NEW
FROM table1
INNER JOIN table2
ON table1.value = table2.DESC
WHERE table1.UPDATETYPE='blah'
) t
SET t.OLD = t.NEW
It depends if the inline view is considered updateable by Oracle
( To be updatable for the second statement depends on some rules listed
here ).
ORACLE SQL UPDATE with INNER JOIN isn't working
Oracle does not support this MySQL-style update join syntax. But, you may use a correlated subquery instead:
UPDATE orders AS o
SET total_price_cache = (SELECT SUM(total_price) FROM order_lines ol
WHERE ol.order_id = o.order_id);
SQL JOIN with UPDATE
Your join is wrong (You are using FROM in UPDATE)
This syntax for JOIN is not for ORACLE
UPDATE TBL_TEST2
SET TBL_TEST2.NAME = 'DONE'
FROM TBL_TEST2
INNER JOIN TBL_TEST1 ON TBL_TEST2.DISTRICT = TBL_TEST1.DISTRICT
WHERE TBL_TEST2.DISTRICT = '1';
In ORACLE A simple way for update joined table is based on the use the the joined select as a table
UPDATE (
SELECT TBL_TEST2.NAME AS OLD_VALUE
FROM TBL_TEST2
INNER JOIN TBL_TEST1 ON TBL_TEST2.DISTRICT = TBL_TEST1.DISTRICT
WHERE TBL_TEST2.DISTRICT = '1' ) T
SET T.OLD_VALUE = 'DONE' ;
Oracle SQL : UPDATE JOIN
You can do this:
UPDATE AlfaGood ag
SET ag.name = 'New text goes here'
--FROM AlfaGood ag -- not an Oracle syntax
WHERE ag.agrid = 'Thats my original text'
AND ag.id = 1
AND EXISTS ( SELECT ca.id FROM SecondAlfa ca WHERE ca.id = 1 );
SQL command not properly ended : Update SET FROM JOIN
In Oracle you do not have the JOIN clause in the UPDATE statement. You can use the following:
UPDATE T1
SET T1.IDC = (SELECT T2.IDC from T2 WHERE T2.IDO = T1.IDC)
Add the WHERE clause if you do not want to update the entire table.
SQL Update Statement using inner Join condition
You do not need the alias on the set. You are already stating that you are updating S_CONTACT
. This answer is for SQL-Server as you appear to be using syntax that is product specific. This syntax isn't valid in Oracle.
UPDATE S_CONTACT
SET ACTIVE_FLG = 'N'
FROM S_CONTACT CON
JOIN S_USER USR
ON CON.PAR_ROW_ID= USR.PAR_ROW_ID
WHERE USR.LOGIN in('BJAME','GWOOD','HTRAME')
For Oracle you can try the below:
UPDATE S_CONTACT
SET S_CONTACT.ACTIVE_FLG = 'N'
WHERE S_CONTACT.PAR_ROW_ID IN
(SELECT CON.PAR_ROW_ID
FROM S_CONTACT CON
INNER JOIN S_USER USR
ON CON.PAR_ROW_ID= USR.PAR_ROW_ID
WHERE USR.LOGIN in('BJAME','GWOOD','HTRAME'))
Update With Inner Join throwing SQL command not properly ended error
The syntax of UPDATE statement in Oracle does not support joins.
A MERGE statement can be used to do this task:
MERGE INTO DEPARTMENT d
USING (
SELECT
rownum as rank, age, deptId
FROM
(SELECT AVG(age) AS age, deptid
FROM employee
GROUP by deptId
ORDER BY age DESC)
) q
ON ( d.DEPTID = q.DEPTID )
WHEN MATCHED THEN UPDATE
SET d.RANK = q.rank
A working demo: http://sqlfiddle.com/#!4/f0f34/2
Related Topics
What Is The Meaning of Kanatype Sensitive Ks and Width Sensitive
Is It Faster to Check If Length = 0 Than to Compare It to an Empty String
Indexed View Vs Indexes on Table
How to Bulk Update with SQL Server
How to Get Rightmost 10 Places of a String in Oracle
Apply Like Over All Columns Without Specifying All Column Names
Making Ssdt Just Generate a SQL Script (And Not Deploy a Database)
"Pivoting" a Table in SQL (I.E. Cross Tabulation/Crosstabulation)
How to Use a Variable in Oracle Script for The Table Name
Postgresql Error: 42P01: Relation "[Table]" Does Not Exist
Oracle Text Escaping with Curly Braces and Wildcards
Adding Extra Column to View, Which Is Not Present in Table
How to Concat Multiple Rows into One Column in SQL Server
How to Multiply a Single Row with a Number from Column in Sql
How to Insert N Rows of Default Values into a Table
Drop Foreign Keys Generally in Postgres
How to Insert Distinct Records from Table a to Table B (Both Tables Have Same Structure)