Oracle Update query with joins - oracle

I do know update clause doesn't work with joins in Oracle.
update table1 Pr
set code = (select t2.class_attr_value from table2 t2
where class_attr_name = 'sample' and Pr.epcclass_id = t2.epcclass_id)
I would be thankful if someone can help me modify my query so that I don't get the error of SQL Command not ended properly.

Your Query seems okay to me I just added Table Alias. Your query will update all records in table1. What error you are getting...??
Suggestions,
a) Unless it's the intent that you want to update all records, add a where clause in the query to avoid updating all records...
b) If you are getting (ORA-01427: single-row subquery returns more than one row) then means corelated sub query (within brackets) is missing some condition to make it fetch only 1 row per epcclass_id.
update table1 Pr
set Pr.code = (select t2.class_attr_value
from table2 t2
where t2.class_attr_name = 'sample'
and t2.epclass_id = Pr.epcclass_id
);

Try this:
UPDATE table1 Pr INNER JOIN table2 t2
ON t2.class_attr_name = 'sample' AND Pr.epcclass_id = t2.epcclass_id
SET Pr.code = t2.class_attr_value

Related

Update table with values of another table

I'm trying to update a table via subquery but i get following error:
ORA-01427: single-row subquery returns more than one row
01427. 00000 - "single-row subquery returns more than one row"
I would like to insert the content of a third table in the column.
My query:
UPDATE GH212_TABLE1
SET GH212_LINK = (SELECT GH201_TABLE1.GH201_ATTRIBUTEX
FROM GH210_TABLE3
LEFT JOIN GH201_TABLE1
ON GH210_TABLE3.GH210_GH201_ID = GH201_TABLE1.GH201_ID
INNER JOIN GH212_TABLE1
ON GH212_TABLE1.GH212_GH210_ID = GH210_ID
WHERE GH212_TABLE1.GH212_GH210_ID=GH210_TABLE3.GH210_ID
GROUP BY GH201_ATTRIBUTEX)
WHERE GH212_TABLE1.GH212_ATTRIBUTEY='11';
I'm not sure how to link the tables right, so that i get the attribute from one specific object.
Any help would be much appreciated.
Cheers,
Fabi
EDIT: Thank you for your reply! I was well of the Problem with the multiple rows, but i somehow couldn't resolve it. Even when i tried the distinct query. But the solution from William Robertson seems to work, thanks a lot!!
A bit of a guess as I don't have your data or business logic, but perhaps you wanted something more like the following. I've removed the second instance of gh212_table1 from the subquery and instead linked t3 back to the table being updated:
update gh212_table1 t
set gh212_link =
( select distinct t1.gh201_attributex
from gh210_table3 t3
left join gh201_table1 t1 on t1.gh201_id = t3.gh210_gh201_id
where t3.gh210_id = t.gh212_gh210_id )
where gh212_table1.gh212_attributey = '11';
There could still be a problem with this, though, if there are rows in gh212_table1 for which the subquery finds no row, as for those rows gh212_link will be set to null. If that is a problem, you might try rewriting it as a merge:
merge into gh212_table1 tgt
using ( select distinct t3.gh210_id, t1.gh201_attributex
from gh210_table3 t3
left join gh201_table1 t1 on t1.gh201_id = t3.gh210_gh201_id ) src
on ( src.gh210_id = tgt.gh212_gh210_id )
when matched then update
set tgt.gh212_link = src.gh201_attributex;
As you are fetching gh201_attributex from an outer join, it will be null whenever there is no row in gh201_table1 for a gh210_table3 row. Is that what you want? In the merge version, if you make it an inner join then the merge will only be applied where a row exists.
SELECT GH201_TABLE1.GH201_ATTRIBUTEX
FROM GH210_TABLE3
LEFT JOIN GH201_TABLE1
ON GH210_TABLE3.GH210_GH201_ID = GH201_TABLE1.GH201_ID
INNER JOIN GH212_TABLE1
ON GH212_TABLE1.GH212_GH210_ID = GH210_ID
WHERE GH212_TABLE1.GH212_GH210_ID=GH210_TABLE3.GH210_ID
GROUP BY GH201_ATTRIBUTEX
This query may give you multiple row values, due to this you are getting this exception
ORA-01427: single-row subquery returns more than one row 01427. 00000 - "single-row subquery returns more than one row"
Ensure that your sub-query return single row value.

Update statement with joins in Oracle

I need to update one column in table A with the result of a multiplication of one field from table A with one field from table B.
It would be pretty simple to do this in T-SQL, but I can't write the correct syntax in Oracle.
What I've tried:
UPDATE TABLE_A
SET TABLE_A.COLUMN_TO_UPDATE =
(select TABLE_A.COLUMN_WITH_SOME_VALUE * TABLE_B.COLUMN_WITH_PERCENTAGE
from TABLE_A
INNER JOIN TABLE_B
ON TABLE_A.PRODUCT_ID = TABLE_B.PRODUCT_ID
AND TABLE_A.SALES_CHANNEL_ID = TABLE_B.SALES_CHANNEL_ID)
WHERE TABLE_A.MONTH_ID IN (201601, 201602, 201603);
But I keep getting errors. Could anybody help me, please?
I generally prefer to use the below format for such cases since this will ensure there's no update performed if there's no data in the table(query extracted temp table) whereas in the above solution provided by Brian Leach will update the new value as null if there's no record present in the 2nd table but exists in the first table.
UPDATE
(
select TABLE_A.COLUMN_TO_UPDATE
, TABLE_A.PRODUCT_ID
, TABLE_A.COLUMN_WITH_SOME_VALUE * TABLE_B.COLUMN_WITH_PERCENTAGE as value
from TABLE_A
INNER JOIN TABLE_B
ON TABLE_A.PRODUCT_ID = TABLE_B.PRODUCT_ID
AND TABLE_A.SALES_CHANNEL_ID = TABLE_B.SALES_CHANNEL_ID
AND TABLE_A.MONTH_ID IN (201601, 201602, 201603)
) DATA
SET DATA.COLUMN_TO_UPDATE = DATA.value;
This solution can cause key preserved value issues which shouldn't be an issue here since i expect a single row in both the tables for one product(ID).
More on Key Preserved table concept in inner join can be found here
https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:548422757486
#Jayesh Mulwani raiesed a valid point, this will set the value to null if there is no matching record. This may or may not be the desired result. If it isn't, and no change is desirect, you can change the select statement to:
coalesce((SELECT table_b.column_with_percentage
FROM table_b
WHERE table_a.product_id = table_b.product_id AND table_a.sales_channel_id = table_b.sales_channel_id),1)
If this is the desired outcome, Jayesh's solution will be more efficient as it will only update matching records.
UPDATE table_a
SET table_a.column_to_update = table_a.column_with_some_value
* (SELECT table_b.column_with_percentage
FROM table_b
WHERE table_a.product_id = table_b.product_id
AND table_a.sales_channel_id = table_b.sales_channel_id)
WHERE table_a.month_id IN (201601, 201602, 201603);

ORACLE - Update Multiple Columns with Values from Nested Join

I'm practically new in using oracle and I bumped into a blocker. Below is the query that I created based on what I have researched online to update multiple columns of a table with values from a nested join statement.
UPDATE
(
SELECT
A.COLUMN1 OLD_COLUMN1,
BC.COLUMN1 NEW_COLUMN1,
A.BALANCE OLD_COLUMN2,
BC.COLUMN2_MIN NEW_COLUMN2,
A.COLUMN3 OLD_COLUMN3,
BC.COLUMN3 NEW_COLUMN3
FROM TABLE_A A
INNER JOIN
(
SELECT B.TWWID,
B.ITEMDATE,
B.COLUMN2_MIN,
C.COLUMN3,
C.COUNTRYID,
C.COLUMN1
FROM TABLE_B B
LEFT OUTER JOIN TABLE_C C
ON TO_CHAR(B.ID) = TO_CHAR(C.ID)
) BC
ON A.ID = BC.ID
AND A.DATE = BC.DATE
)ABCUPDATE
SET ABCUPDATE.OLD_COLUMN1 = ABCUPDATE.NEW_COLUMN1,
ABCUPDATE.OLD_COLUMN2 = ABCUPDATE.NEW_COLUMN2,
ABCUPDATE.OLD_COLUMN3 = ABCUPDATE.NEW_COLUMN3;
Selecting the sub-query returns the expected results but when I run the update script as a whole an error is returned.
ORA-01779: cannot modify a column which maps to a non key-preserved
table
Can anyone please explain why I encounter this error and what adjustments can I do to the script to make it work?
Thanks in advance!

Update SQL Query with Join on 2 tables

I have a requirement to read from 2 tables once read i have to update the falg on both table.
My SQL query
SELECT t1.KUNNR,t1.SETT_KEY,t1.QUART_START,t1.QUART_END,t2.PAY_METH,t2.MAT_NDC,t2.AMOUNT
FROM TSAP_REBATE_MEDI t1
INNER JOIN TSAP_REBATE_LINE t2 ON t1.KUNNR=t2.KUNNR AND t1.SETT_KEY=t2.SETT_KEY
WHERE t1.PROCESSING_STATUS = 'N' AND t2.PROCESSING_STATUS = 'N'
This is working fine now i need an update query for the same where PROCESSING_STATUS is set to 'P' on both tables.
You cannot update two tables at the same time. Run two separate UPDATE statements of the following nature
UPDATE t1
SET COLUMN = VALUE
FROM TSAP_REBATE_MEDI t1
INNER JOIN TSAP_REBATE_LINE t2
ON t1.KUNNR=t2.KUNNR
AND t1.SETT_KEY=t2.SETT_KEY
WHERE t1.PROCESSING_STATUS = 'N'
AND t2.PROCESSING_STATUS = 'N'
/* Add any other conditions */
However, if you want them both to be updated (or neither one), wrap both updates in a BEGIN TRANSACTION - COMMIT

How can I improve this update script?

I want to update a table in oracle which has 155.750 rows.
I write this:
UPDATE Table1 R
SET R.TOTAL =
(SELECT SUM(T.TOTALS_TO_DATE)
FROM Table2 T
WHERE T.ID= R.ID
AND T.TYPE = 'type5');
Table1 has index at ID
Table2 has indexes at ID and TYPE.
This is not responding. How can edit this to run fastly?
If I write this select it runs fastly.
SELECT SUM(T.TOTALS_TO_DATE),R.ID
FROM Table2 T,Table1 R
WHERE T.ID= R.ID
AND T.TYPE = 'type5'
group by R.ID ;
This runs but I do not understand why the update script takes 3000seconds.
Thanks.
try to use MERGE statement
MERGE INTO table1 R using
( SELECT SUM(T.TOTALS_TO_DATE) S, T.ID
FROM Table2 T
WHERE T.TYPE = 'type5'
group by T.ID
) T
ON ( R.ID = T.ID)
WHEN MATCHED THEN UPDATE SET R.TOTAL = T.S
;
You forgot to put the where condition in the Update script. Hence it is updating the whole table1 and hence it is taking time.
For the select query you have mentioned the where clause which is running faster.
Edit:-
Check our this link
Here are some of the steps which you can do to improve your update command run faster.
Removing index on the column to be updated.
Executing the update in smaller batches.
Disabling Delete triggers.
Replacing Update statement with a Bulk-Insert operation.

Resources