Oracle: update using values from other tables - oracle

I've got the following Update but I don't want to copy the values manually.
I prefer to extract them using a query.
Should I use PL/SQL or is there an SQL formulation?
The query that I use to obtain the values I've copied manually into the update is not key preserving ("Key-preserved table concept in join view").
UPDATE wkf_cronologia
SET swkf_stato_workflow_id = 'o3gE1tlSdcDIC6FF',
swkf_data_ini = TO_TIMESTAMP ('19-06-2010 18:28:10,556000000','DD-MM-RRRR HH24:MI:SS,FF'),
swkf_versione = 0,
SPWKF_STATO_PUBBLICO_ID = '*1UNICOO',
SPWKF_DATA_INI = TO_TIMESTAMP ('01-01-0001 00:00:00,000000000', 'DD-MM-RRRR HH24:MI:SS,FF'),
SPWKF_VERSIONE = 0
WHERE wkfc_cronologia_id = 'ApAJ0qCudNphjLxj';

You can use a subquery:
UPDATE wkf_cronologia
SET (swkf_stato_workflow_id,
swkf_data_ini,
swkf_versione,
SPWKF_STATO_PUBBLICO_ID,
SPWKF_DATA_INI,
SPWKF_VERSIONE) = (select a,b,0,c,d,e
from another_table
where something=wkf_cronologia.swkf_stato_workflow_id)
WHERE swkf_versione is null;

Related

An attempt was made to insert or update columns error while updating columns in Oracle

I want to update the column with some details. But I am getting this error:
An attempt was made to insert or update columns of a join view which map to a non-key-preserved table.
Here is my query:
UPDATE
(
SELECT a.SPAN_LINK_ID, a.SPAN_TYPE, a.NE_LENGTH as OLD, b.MAINT_ZONE_NE_SPAN_LENGTH as NEW
FROM app_fiberinv.tbl_fiber_inv_cmpapproved_info a
INNER JOIN app_fiberinv.tbl_fiber_inv_jobs b
ON a.SPAN_LINK_ID = b.LINK_ID
WHERE a.SPAN_LINK_ID IN ('DLHI_5202','TCPP_6004')) t
SET t.OLD = t.NEW;
How can I fix this?
What if you skip the join view and use e.g. merge?
MERGE INTO tbl_fiber_inv_cmpapproved_info a
USING tbl_fiber_inv_jobs b
ON (a.span_link_id = b.span_link_id)
WHEN MATCHED
THEN
UPDATE SET a.ne_length = b.maint_zone_ne_span_length
WHERE a.span_link_id IN ('DLHI_5202', 'TCPP_6004');

Oracle trying to update a table by joining a non indexed table

I tried looking for a similar example to my problem but could not reproduce the solution to my success.
I have 2 tables, Controller and Actions.
The Actions table has the columns Step, Script, Description, Wait_Until and Ref_Code.
The Controller table can only be joined on the Action table by the Ref_Code.
The Action table cannot have a PK because for each Ref_Code there is a Step to be taken.
Im getting an error when trying to update the Controller table using a merge statement:
ORA-30926: unable to get a stable set of rows in the source tables
My merge statement is as follows:
MERGE INTO DSTETL.SHB_FTPS_CONTROLLER ftpsc
USING (SELECT DISTINCT FTPSC.SESSION_ID,
FTPSC.ORDER_DATE,
sa.step,
sa.next_step,
LAST_ACTION_TMSTMP,
SA.ACTION_SCRIPT,
sa.ref_code,
SA.WAIT_UNTIL
FROM DSTETL.SHB_FTPS_CONTROLLER ftpsc, DSTETL.SHB_ACTIONS sa
WHERE SA.REF_CODE = FTPSC.REF_CODE
AND SA.STEP > ftpsc.curr_step
AND sa.step = ftpsc.next_step) v1
ON (v1.REF_CODE = FTPSC.REF_CODE)
WHEN MATCHED
THEN
UPDATE SET FTPSC.LAST_ACTION_TMSTMP = CURRENT_TIMESTAMP,
ftpsc.next_step = v1.next_step,
ftpsc.curr_step = v1.STEP,
ftpsc.action_script = v1.action_script
WHERE CURRENT_TIMESTAMP >= v1.LAST_ACTION_TMSTMP + v1.WAIT_UNTIL;
COMMIT;
I tried doing this using a normal update as well but Im getting ORA-01732: data manipulation operation not legal on this view.
UPDATE (SELECT FTPSC.SESSION_ID,
FTPSC.ORDER_DATE,
FTPSC.CURR_STEP,
FTPSC.NEXT_STEP,
FTPSC.ACTION_SCRIPT,
sa.step, --New Step
sa.next_step AS "NNS", --New Next Step
FTPSC.LAST_ACTION_TMSTMP,
SA.ACTION_SCRIPT AS "NAS", --New action script
sa.ref_code,
SA.WAIT_UNTIL
FROM DSTETL.SHB_FTPS_CONTROLLER ftpsc
LEFT JOIN
DSTETL.SHB_ACTIONS sa
ON SA.REF_CODE = FTPSC.REF_CODE
AND SA.STEP > ftpsc.curr_step
AND sa.step = ftpsc.next_step) t
SET t.curr_step = t.step,
t.LAST_ACTION_TMSTMP = CURRENT_TIMESTAMP,
t.next_step = t."NNS",
t.action_script = t."NAS";
COMMIT;
Any advice would be appreciated, I already understand this is because the Action table has multiple Ref_Codes but REF_CODE||STEP is unique. And the output of:
SELECT DISTINCT FTPSC.SESSION_ID,
FTPSC.ORDER_DATE,
sa.step,
sa.next_step,
LAST_ACTION_TMSTMP,
SA.ACTION_SCRIPT,
sa.ref_code,
SA.WAIT_UNTIL
FROM DSTETL.SHB_FTPS_CONTROLLER ftpsc, DSTETL.SHB_ACTIONS sa
WHERE SA.REF_CODE = FTPSC.REF_CODE
AND SA.STEP > ftpsc.curr_step
AND sa.step = ftpsc.next_step;
Is how I want the Controller table to be updated like.
Thanks in advance.
It sounds like what you want to do is: update each row in the Controller table with the matching "next step" details from the Actions table. But your Merge statement is querying the Controller table twice, which confuses things.
Is this what you're trying to do?
MERGE INTO DSTETL.SHB_FTPS_CONTROLLER ftpsc
USING (SELECT
step,
next_step,
ACTION_SCRIPT,
ref_code,
WAIT_UNTIL
FROM DSTETL.SHB_ACTIONS
) sa
ON (sa.REF_CODE = FTPSC.REF_CODE)
WHEN MATCHED
THEN
UPDATE SET FTPSC.LAST_ACTION_TMSTMP = CURRENT_TIMESTAMP,
ftpsc.next_step = sa.next_step,
ftpsc.curr_step = sa.STEP,
ftpsc.action_script = sa.action_script
WHERE CURRENT_TIMESTAMP >= ftpsc.LAST_ACTION_TMSTMP + sa.WAIT_UNTIL
AND SA.STEP > ftpsc.curr_step
AND sa.step = ftpsc.next_step;
EDIT: updated query
EDIT2: So, in your original query, in the USING section you were selecting the rows in the Controller table that you wanted to update... but you never joined those rows to the Controller table from the MERGE INTO section to match them up. Having the same alias "ftpsc" just made it less clear that they're two separate objects in the query, and which one you wanted to update.
Honestly I don't really understand why Oracle won't let you update columns that appear in the USING..ON clause. It apparently works fine in SQL Server.

Using Merge in Oracle for updating a parent table using Joins

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

Merge using update insert new rows

I have below merge query where i want to update the date and for perfromance issue i am using ROWID logic.
But i would like to know does it anyhow inserts new rows ? I just want to update the table TEST_GRP and dont want any insertion of new rows.
As i am using ROWID logic for the first time i am really not sure whether it insert new rows or just update the table.
MERGE INTO TEST_GRP tgt
USING (SELECT ID,
ROWID r_id,
row_number() over (partition by ID ORDER BY DT_DATE) rn
FROM TEST_GRP) src
ON (tgt.rowid = src.r_id AND src.rn = 1)
WHEN MATCHED THEN
UPDATE SET DT_DATE = to_date('01.01.2017', ''dd.mm.yyyy'')
WHERE DT_DATE != to_date('01.01.2016', ''dd.mm.yyyy'')
and DB_NAME = 'ARD';
It will update the rows with no problem and does not insert new rows.
At your UPDATE statment probalie it can cause you problem the quote at format mask SET DT_DATE = to_date('01.01.2017', ''dd.mm.yyyy'') DT_DATE != to_date('01.01.2016', ''dd.mm.yyyy'')
You don't have to add insert clause to mergestatement as stated in the docs :
merge_update_clause ... You can specify this clause by itself or with the
merge_insert_clause
And you don't have in it your code so not insert(s) will happen.
merge_insert_clause:

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 ...)

Resources