Using Merge in Oracle for updating a parent table using Joins - oracle

I have a SQL statement as below, I couldn't execute the statement in Oracle as it doesn't support Joins in Update. I have tried using updating using a temp table and completed the job, however, I would like to use the Merge statement and failed to write the code.
Let me know if there is a possibility in Oracle use joins in an update which doesn't add any performance overhead.
UPDATE A SET
YearStartPD = B.PERIOD_CODE,
YearEndPD = A.PERIOD_CODE,
PY_YearStartPD = C.PERIOD_CODE,
PY_YearEndPD = A.PY_WeekEndPD
FROM dbo.DIM_TIME A
INNER JOIN
(
select PERIOD_CODE,WEEK_PERIOD_CODE,YEAR_CODE from dbo.DIM_TIME
WHERE WEEK_PERIOD_CODE = '01'
) B ON B.Year_Code = A.Year_Code
LEFT JOIN
(
select PERIOD_CODE,WEEK_PERIOD_CODE,YEAR_CODE from dbo.DIM_TIME
WHERE WEEK_PERIOD_CODE = '01'
) C ON C.Year_Code = A.Year_Code - 1

Related

Oracle mutliple left outer joins only max() rows

I have a statement that is used quiet often but does perform pretty poorly.
So i want to optimize it as good as possible. The statement consist of various parts and unions.
One part that is pretty costly is the following.
select *
from rc050 F
LEFT OUTER JOIN
(SELECT fi_nr,
fklz,
rvc_status,
lfdnr,
txt
FROM rc0531 temp
WHERE lfdnr =
(SELECT MAX(lfdnr) FROM rc0531 WHERE fi_nr = temp.fi_nr AND fklz = temp.fklz
)
) SUB_TABLE1
ON F.fklz = SUB_TABLE1.fklz
AND F.fi_nr = SUB_TABLE1.fi_nr
LEFT OUTER JOIN
(SELECT fi_nr,
fklz,
rvc_status,
lfdnr,
txt
FROM rc0532 temp
WHERE lfdnr =
(SELECT MAX(lfdnr) FROM rc0532 WHERE fi_nr = temp.fi_nr AND fklz = temp.fklz
)
) SUB_TABLE2
ON F.fklz = SUB_TABLE2.fklz
AND F.fi_nr = SUB_TABLE2.fi_nr
LEFT OUTER JOIN
(SELECT fi_nr,
fklz,
rvc_status,
lfdnr,
txt
FROM rc05311 temp
WHERE lfdnr =
(SELECT MAX(lfdnr)
FROM rc05311
WHERE fi_nr = temp.fi_nr
AND fklz = temp.fklz
)
) SUB_TABLE11
ON F.fklz = SUB_TABLE11.fklz
AND F.fi_nr = SUB_TABLE11.fi_nr
where F.fklz != ' '
This is a part where I have to load from these rc0531 ... rc05311 tables
what there latest entry is. There are 11 of these tables so this is broken down.
As you can see I'm currently joining each table via subquery and need only the latest entry so i need an additional subquery to get the max(lfdnr).
This all works good so far but i wanna know if there is a more efficient way to perform this.
In my main select I need to be able to address each column from each of these tables.
Do you guys have any suggestions ?
This currently runs in 1.3 sec on 13k rows to get a decent boost this should get down to 0.1 sec or so. Again this is only one problem in a bigger statement full of unefficient declarations.
It's not possible to optimize a SQL query. Oracle is going to take your query and determine an execution plan that it uses to determine the information you've asked for. You might completely rewrite the query and, if it leads to the same execution plan, you'll get exactly the same performance. To tune a query, you need to determine the execution plan.
You may well benefit from an index on each of these tables, on the (fi_nr, fklz) columns or possibly even (fi_nr, fklz, lfdnr), depending on how selective that gets. There's no way to tell in advance from this information, you'll just have to try.
You should also remove the select * and select only the columns you want. If it's possible to get just the needed information from an index, Oracle will not need to retrieve the actual table row.
replace the left joins from :
LEFT OUTER JOIN (
SELECT fi_nr,fklz,rvc_status,lfdnr,txt FROM rc0531 temp
WHERE lfdnr = (SELECT MAX(lfdnr) FROM rc0531 WHERE fi_nr = temp.fi_nr AND fklz = temp.fklz)
) SUB_TABLE1
ON F.fklz = SUB_TABLE1.fklz
AND F.fi_nr = SUB_TABLE1.fi_nr
to this:
LEFT OUTER JOIN (
SELECT fi_nr,fklz,rvc_status,lfdnr,txt FROM rc0531 inner join
(SELECT fi_nr, fklz, MAX(lfdnr) lfdnr FROM rc0531 group by fi_nr, fklz)x on x.fi_nr=rc0531.fi_nr and x.fklz=rc0531.fklz and x.lfdnr=rc0531.lfdnr
) SUB_TABLE1
ON F.fklz = SUB_TABLE1.fklz
AND F.fi_nr = SUB_TABLE1.fi_nr
let me know if it got to 0.1 sec, i think it will go

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 query in pre sql of source qualifier is running but not commiting the table?

Below given query is executed using Source qualifier in Informatica.
Pre SQL has the below query.
Update CTLSTAGE.VMR226DEV_HSD_SUB A
set A.ATM_IP_IND = 'ATM'
where (A.SW_SITE_CD,A.DEV_NM) = (
select SW_SITE_CD,DEV_NM
from CTLSTAGE.ATM_IP_REF
where FTTC_E_IND = 'Y'
) ;
COMMIT ;
Which is running but not committing in database.
I presume it's running fine. Add additional statements to diagnose, like:
insert into someAuditTable
select SW_SITE_CD,DEV_NM from CTLSTAGE.ATM_IP_REF where FTTC_E_IND = 'Y'
and
insert into someAuditTable2
select * from CTLSTAGE.VMR226DEV_HSD_SUB A where (A.SW_SITE_CD,A.DEV_NM) = (
select SW_SITE_CD,DEV_NM
from CTLSTAGE.ATM_IP_REF
where FTTC_E_IND = 'Y'
) ;
BTW:
Does this kind of tuple comparison work fine? Looks odd to me:
(A.SW_SITE_CD,A.DEV_NM) = (select SW_SITE_CD,DEV_NM ...)

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

ORA-01779 on Join Update

I'm developing a web application on vb.net with Oracle as DB and I'm having some problems to update a table by using joins.
Since I'm kind of a newbie on Oracle, I can't make my query go on...i've been reading and I knew that oracle doesn't supports Joins on UPDATE, so i searched for alternatives and I finished on this:
UPDATE (SELECT pda.id_propuesta
FROM abd_prop_det_archivos pda
INNER JOIN abd_participantes_invitados pi
ON (pda.id_solicitud = pi.id_solicitud)
AND pi.id_solicitud = :id_solicitud
AND pi.rut = :rut)
SET id_propuesta = :id_propuesta
I'm using Oracle 11g.
It appears that you want a WHERE EXISTS clause
UPDATE abd_prop_det_archivos pda
SET ID_PROPUESTA = :ID_PROPUESTA
WHERE EXISTS( SELECT 1
FROM ABD_PARTICIPANTES_INVITADOS pi
WHERE pda.id_solicitud = pi.id_solicitud)
AND pi.id_solicitud = :id_solicitud
AND PI.RUT = :RUT )

Resources