Table is mutating error - oracle

I wrote the following query to update the amount column in work_order_coding_tab from the values fetched by work_order_coding view.
merge into work_order_coding_tab A
using work_order_coding B
on (A.WO_NO = B.WO_NO AND A.ROW_NO=B.ROW_NO)
when matched then update set A.amount = B.sales_price_amount
where
A.WO_NO = B.WO_NO AND
A.ROW_NO=B.ROW_NO
AND B.work_order_cost_type_db = 'M'
AND B.order_no IS NULL
AND B.catalog_no IS NOT NULL
AND A.amount is not null and A.amount <> B.sales_price_amount and B.contract like 'TZ%'
and abc.active_separate_api.get_line_no(B.wo_no) =2
AND A.WO_NO=2002 AND A.ROW_NO=3921;
But I'm getting the error, ora-04091 table is mutating, figure or function may not see it. I wrote the above query instead of following , as oracle doesn't support this.
UPDATE
from
work_order_coding_tab A
inner join work_order_coding B
on A.WO_NO = B.WO_NO AND A.ROW_NO=B.ROW_NO
where
A.WO_NO = B.WO_NO AND
A.ROW_NO=B.ROW_NO
AND B.work_order_cost_type_db = 'M'
AND B.order_no IS NULL
AND B.catalog_no IS NOT NULL
AND A.amount is not null and A.amount <> B.sales_price_amount and B.contract like 'TZ%'
and abc.active_separate_api.get_line_no(B.wo_no) =2;
Can any on please help me to identify the issue of this.

Related

Joining 3 tables doesnt work, should I use a subquery for the below

I have this query.
SELECT re_current_benefits.prospect_nbr, qo_quote.quote_id, hra_ind, quote_type, effective_date, quote_expiration_ind, mhs_lob_code
FROM re_current_benefits
INNER JOIN qo_quote ON qo_quote.prospect_nbr = re_current_benefits.prospect_nbr
WHERE hra_ind = 'Y' AND quote_type = 'R' AND quote_expiration_ind IS NULL AND mhs_lob_code NOT IN 'DTL1' AND mhs_lob_code NOT IN 'DTL2'
And I need to pull the prospect_nbr from here, I also need to add a filter saying effective_date = renewal_date but if I do that by joining all 3 tables together I get 0 results which should not be the case.
SELECT prospect_nbr, rmr_run_status, renewal_date
FROM re_group
WHERE rmr_run_status = ANY ('S', 'W')

cant update a column from table it returns single-row subquery returns more than one

When i execute the following query, i get the message like
Ora-01427 single-row subquery returns more than one row
I am trying to update "City" column in Table A From another table.
How would I do this?
table A: Name, PER_code(it also has duplicated value or null), city, PD_code
table B: Name, PER_code(No duplicated value,Maybe null), city, Postal_code
The update statement:
UPDATE A
SET (A.city) =
(SELECT B.city
FROM B
INNER JOIN A
ON A.per_code=B.per_code
WHERE A.per_code is not null)
Since there are duplicate values but you select only one field, you modify your query from
UPDATE A SET (A.city) = (SELECT B.city FROM B INNER JOIN A ON
A.per_code=B.per_code WHERE A.per_code is not null)
to
UPDATE A SET (A.city) = (SELECT DISTINCT B.city FROM B INNER JOIN A ON
A.per_code=B.per_code WHERE A.per_code is not null)
The distinct operator will allow you to keep a single value if it's duplicated in the table B. If there are multiple distinct values, you will have to look at your data and make a decision about which value should be used in the other table.
You can also try MERGE INTO selecting DISTINCT records.
MERGE INTO A d
USING
( SELECT DISTINCT per_code, city FROM B ) s
ON ( s.per_code = d.per_code )
WHEN MATCHED THEN UPDATE SET d.City = s.City
WHERE d.per_code IS NOT NULL;
I think you intend a correlated subquery:
UPDATE A
SET city = (SELECT B.city
FROM B
WHERE A.per_code = B.per_code
)
WHERE A.per_code is not null;
EDIT:
The above should work given the constraints in the original question. If it does not, it is easily adaptable:
UPDATE A
SET city = (SELECT B.city
FROM B
WHERE A.per_code = B.per_code AND rownum = 1
)
WHERE A.per_code is not null;

Updating error for a given query

If the following query is written, I'm getting the error invalid B.WO_NO. If the query is written without the WHERE clause, all the amount values in work_order_coding_tab is said updated. But I don't need to update all the data in the table. But instead I need to update only rows select by , the inner select. Any suggestions for what I can tried out. Please help
UPDATE work_order_coding_tab A
A.amount = (SELECT B.sales_price_amount
FROM work_order_coding B
WHERE A.WO_NO = B.WO_NO AND
A.ROW_NO=B.ROW_NO
AND B.work_order_cost_type_db = 'M'
AND B.order_no IS NULL
AND B.catalog_no IS NOT NULL
AND A.amount is not null and A.amount <> B.sales_price_amount and B.contract like 'TZ%'
and abc.active_separate_api.get_line_no(B.wo_no) =2)
WHERE A.WO_NO = B.WO_NO AND
A.ROW_NO=B.ROW_NO
I don't think you even need the current outer WHERE clause, i.e. just use this:
UPDATE work_order_coding_tab A
SET A.amount = (SELECT B.sales_price_amount
FROM work_order_coding B
WHERE
A.WO_NO = B.WO_NO AND
A.ROW_NO = B.ROW_NO AND
B.work_order_cost_type_db = 'M' AND
B.order_no IS NULL AND
B.catalog_no IS NOT NULL AND
A.amount IS NOT NULL AND
A.amount <> B.sales_price_amount AND
B.contract LIKE 'TZ%' AND
abc.active_separate_api.get_line_no(B.wo_no) = 2)
The error is happening because the alias B does not exist and is not available outside of the subquery. But your WHERE logic inside the correlated subquery already does what the outer WHERE clause attempts to do.
Note that you might actually want an outer WHERE clause, e.g. if you wanted to restrict the updating of amounts to certain records in the work_order_coding_tab table. Typically, it is best practice to have some restriction on an update, unless of course you really intend to update the entire table.

Problems updating query with inner join

Can anyone please assist in getting this one query to work. I am trying to update status of a column in a table having joined to other tables
Here is the query
update
(select I.account_id, I.sts, I.name_id, CI.CRM_TYPE, I.comments
from PPInters I
inner join DW.CUST CT
on I.account_id = CT.account_id
where
I.sts is null
AND I.comments IS NOT NULL
AND CT.CUSTTYPe = 'INTNL') T
SET T.STS = 'D'
WHERE T.account_id IN (2000208927,380166014,190180447,166078041,105029075 )
I am getting "ORA-01779: cannot modify a column which maps to a non key-preserved table" error
What I am trying to do here is to set I.STS = 'D' for some 700 records pulled up using this query
select I.account_id, I.sts, I.name_id, CI.CRM_TYPE, I.comments
from PPInters I
inner join DW.CUST CT
on I.account_id = CT.account_id
where
I.sts is null
AND I.comments IS NOT NULL
AND CT.CUSTTYPe = 'INTNL'
I appreciate it
Assumming that account_id is a primary key kolumn in table PPInters,
that is it's value uniquely identifies records in this table:
UPDATE PPInters
SET STS = 'D'
WHERE account_id IN (
select I.account_id
/*, I.sts, I.name_id, CI.CRM_TYPE, I.comments */
from PPInters I
inner join DW.CUST CT
on I.account_id = CT.account_id
where
I.sts is null
AND I.comments IS NOT NULL
AND CT.CUSTTYPe = 'INTNL'
)
AND account_id IN (2000208927,380166014,190180447,166078041,105029075 )

Oracle update statement error

I need to update a column called assignment_type_desc in a table randm_sampler with values from source table clm_snapshot based on matching claim_id. The problem is that there are two records in clm_snapshot with NULL claim_id's and different values for assignment_type_desc. I do not need these records, hence I included NOT NULL condition in the update statement. But the update statement still returns single row subquery returns more than one row error.
UPDATE RANDM_SAMPLER SET ASSIGNMENT_TYPE_DESC =
(SELECT DISTINCT A.ASSIGNMENT_TYPE_DESC
FROM CLM_SNAPSHOT A,
RANDM_SAMPLER B
WHERE A.CLAIM_ID = B.CLAIM_ID
AND A.CURRENT_SNAPSHOT_IND='Y'
AND A.HO_CONSULTANT_SEQ_NBR = (SELECT MAX(HO_CONSULTANT_SEQ_NBR)
FROM CLM_SNAPSHOT C
WHERE A.CLAIM_ID = C.CLAIM_ID
AND C.CLAIM_ID IS NOT NULL
GROUP BY CLAIM_ID)
AND A.CLAIM_ID IS NOT NULL )
I am absolutely positive that the duplicates are from the records which have NULL values for the claim_id. But the NOT NULL condition doesn't seem to be effective here. Can someone help me out with this?
Try to following UPDATE statement:
UPDATE RANDM_SAMPLER SET ASSIGNMENT_TYPE_DESC =
(SELECT DISTINCT A.ASSIGNMENT_TYPE_DESC
FROM CLM_SNAPSHOT A
WHERE A.CLAIM_ID = RANDM_SAMPLER.CLAIM_ID
AND A.CURRENT_SNAPSHOT_IND='Y'
AND A.HO_CONSULTANT_SEQ_NBR = (SELECT MAX(HO_CONSULTANT_SEQ_NBR)
FROM CLM_SNAPSHOT C
WHERE A.CLAIM_ID = C.CLAIM_ID
AND C.CLAIM_ID IS NOT NULL
GROUP BY CLAIM_ID)
AND A.CLAIM_ID IS NOT NULL )
I've removed the JOIN to RANDM_SAMPLER from the subquery and instead added the condition that really important because it makes the link to the table to be updated:
A.CLAIM_ID = RANDM_SAMPLER.CLAIM_ID
You probably tried the same but adding the table B made things worse. And there was no connection to the outer table.

Resources