Part of the update is not working in Procedure - sql

I have written two update statement in my procedure. For some strange reason first update statement only update some of the record (basically I update more than 100,000 rows). So second update statement works fine all the time. I brainstormed but procedure completes successfully but I am not getting what is the issue. Is there any way I can perform a validation check like how many got updated and and how many not?
1st update statement(Which update only some records sometimes)
UPDATE /*+PARALLEL(A,10,2)*/ VV_ACT_CALL_DET_DIS_EXTRACT A SET PRIORITY =
( SELECT P.PRIORITY
FROM VV_ACT_CALL_DET_DIS P
WHERE P.CALL_ID = A.CALL_ID
AND P.PRODUCT_ID = A.PRODUCT_ID
AND P.IS_DELETED = A.IS_DELETED
AND ROWVAL = 1 )
WHERE EXTRACT_STATUS = 'PENDING'
AND EXISTS
( SELECT B.PRIORITY
FROM VV_ACT_CALL_DET_DIS B
WHERE B.CALL_ID=A.CALL_ID
AND B.PRODUCT_ID = A.PRODUCT_ID
AND B.IS_DELETED = A.IS_DELETED );
2nd Update statement which updates record successfully all the time though condition is same as above
UPDATE /*+PARALLEL(A,10,2)*/ VV_ACT_CALL_DET_DIS_EXTRACT A SET TYPE =
( SELECT P.TYPE_VAL
FROM VV_ACT_CALL_DET_DIS P
WHERE P.CALL_ID = A.CALL_ID
AND P.PRODUCT_ID = A.PRODUCT_ID
AND P.IS_DELETED = A.IS_DELETED
AND ROWVAL = 1 )
WHERE EXTRACT_STATUS = 'PENDING'
AND EXISTS
( SELECT B.TYPE_VAL
FROM VV_ACT_CALL_DET_DIS B
WHERE B.CALL_ID = A.CALL_ID
AND B.PRODUCT_ID = A.PRODUCT_ID
AND B.IS_DELETED = A.IS_DELETED );

You can query the updated row count using SQL%rowcount right after the update statement (before the commit), e.g.:
update ....
if sql%rowcount <> nnn then --or = 0 or ...
raise_application_error(-20001, 'invalid number of rows updated: ' || sql%rowcount);
end if;
Regarding the 'why it is not updating issue': without seeing that actual data it is hard to tell. Can you give us an example data set? Is it possible, that the first statement updates the same number of rows, but data does not change (priority remains the same)?

Related

PL/SQL Update Query

Attempting to update a table I have created with null values from another table I have created in PL/SQL:
I was able to utilize the below update in SQL Server but am running into issues within PL/SQL (dont ask why I am running it in both)
Overall_Inventory = Table created with some populated values and some null valuse; this is the table requiring updates to those null values
task_table = Table also created, but contains value needing to be updated into T1
update dbh.overall_inventory
set dbh.overall_inventory.case_due_date = tsk.TASK_ACTION_TIMESTAMP
from dbh.overall_inventory,
(SELECT tsk.INQ_KEY,
min(tsk.TASK_ACTION_TIMESTAMP) as TASK_ACTION_TIMESTAMP
FROM dbh.task_table tsk
inner join dbh.overall_inventory Inv
on tsk.INQ_KEY = inv.inq_key
where tsk.ACTION_CD = '324'
group by tsk.INQ_KEY
) tsk
where tsk.INQ_KEY = dbh.overall_inventory.inq_key`
Oracle doesn't support from clause in the update statement. In this situation merge statement can be used.
merge into overall_inventory oi
using (select tsk.inq_key,
min(tsk.task_action_timestamp) as task_action_timestamp
from task_table tsk
join overall_inventory Inv
on tsk.inq_key = inv.inq_key
where tsk.action_cd = '324'
group by tsk.inq_key) tsk
on (tsk.inq_key = oi.inq_key )
when matched then
update
set case_due_date = tsk.task_action_timestamp
where case_due_date is null -- as I understood only NULL values
-- need to be updated
Note: Not tested because no sample data and desired result were provided.
I think you're looking for update over a select:
UPDATE (
  SELECT product_id, category_id
  FROM product) st
SET st.category_id = 5
WHERE st.category_id = 4;

need to replace subquery with JOIN

I need to use join in below instead of Subquery.
can anybody help me to rewrite this with JOIN.
update Table1
set status = 'Edited'
where val_74 ='1' and status ='Valid'
and val_35 is not null
and (val_35,network_id) in
(select val_35,network_id from
Table2 where val_35 is not null
and status='Correct_1');
update Table1 b SET (Val_12,Val_13,Val_14)=
(select Val_12,Val_13,Val_14 from
(select Val_35,network_id, Val_12, Val_13, Val_14
from Table2
where Val_34 is not null
and (REGEXP_LIKE(Val_13,'^[0-9]+$'))
and (Val_14 is null or (REGEXP_LIKE(Val_14,'^[0-9]+$')))
group by Val_35,network_id,Val_12,Val_13,Val_14
)
where Val_35 = b.Val_35 and network_id = b.network_id and rownum=1
)
where status = 'PCStep2' and (regexp_like(Val_13,'[MSS]+') or regexp_like(Val_14,'[MSS]+'));
I tried a lot with my less Knowledge In SQL JOINs. but getting multiple erros.
can anybody help me with the queries at the earliest.
Hearty thanks in advance
Actually you can not mix a update statement with a join statement. An update statement always expects exactly one table definition after the update command.
-- ORA-00971: missing SET keyword
update orders o, customers c
set o.order_value = c.account_value
where o.cust_id = c.cust_id
-- works fine
update orders o
set o.order_value = (select c.account_value
from customers c
where c.id = o.cust_id)

How to write a Trigger based on row update

I am first time using a trigger, Now I am facing some problems,
I have 3 tables, InvoiceHead, InvoiceDetails, InventoryMaster .
when I update 'Status' field of InvoiceHead (from 0 to 1), 'Status' fields of InvoiceDetails and InventoryMaster need to be changed based on the updated row.
Reltionships :
InvoiceHead_id=InvoiceDetails_id (FK) and
InventoryMaster_Processid=InvoiceHead_id (FK)
How can write a trigger in InvoiceHead ?
Please help to solve this..
Try this
create trigger your_trigger
on InvoiceHead
after update
as
//declare #status int;
//select #status=i.status from inserted i;
//IF #status == 1
//BEGIN
update d
set d.status = b.status
from InvoiceDetails as d
join inserted as b
on a.InvoiceDetails_id = b.InvoiceHead_id
where b.status == 1;
update m
set m.status = b.status
from InventoryMaster as m
join inserted as b
on m.InventoryMaster_Processid = b.InvoiceHead_id
where b.status == 1;
end
go
But keep in mind that in SQL trigger works on entire update not like rowwise in oracle. so if this trigger will fire for more than one row at a time my code won't work for your requirement..You need to fine tune it..

update rows from joined tables in oracle

I'm trying to migrate some tables into an existing table, I need to perform the updates only where DET_ATTACHMENT_ID equals DET_ATTACHMENT.ID, here's the query I have so far.
UPDATE DET_ATTACHMENT
SET attachment_type = 'LAB', -- being added by the query, to replace the table difference
payer_criteria_id = (
SELECT PAYER_CRITERIA_ID
FROM DET_LAB_ATTACHMENT
WHERE DET_LAB_ATTACHMENT.DET_ATTACHMENT_ID = DET_ATTACHMENT.ID)
WHERE exists(
SELECT DET_ATTACHMENT_ID
FROM DET_ATTACHMENT
JOIN DET_LAB_ATTACHMENT ON (ID = DET_ATTACHMENT_ID)
WHERE DET_ATTACHMENT_ID = DET_ATTACHMENT.ID
the problem with the existing query is that it's setting every row to have an attachment_type of "LAB", and nulling out the payer_criteria_id where it didn't match. What am I doing wrong?
The problem might be that your exists(...) predicate always evaluates to true, thus making the update run for all rows of det_attachment. Try it this way:
UPDATE DET_ATTACHMENT X
SET X.attachment_type = 'LAB',
X.payer_criteria_id = (
SELECT C.PAYER_CRITERIA_ID
FROM DET_LAB_ATTACHMENT C
WHERE C.DET_ATTACHMENT_ID = X.ID
)
WHERE
exists(
SELECT 1
FROM DET_ATTACHMENT A
JOIN DET_LAB_ATTACHMENT B
ON B.DET_ATTACHMENT_ID = A.ID
where B.det_attachment_id = X.id
)
;

T-SQL Query to check if related col is true and update another table col

I have this 2 tables SupplierOrder and SupplierOrderDetails which are linked by SupplierOrder PK. Now I have this col called isComplete in the SupplierOrder table which I want o update to true once all the values in the SupplierORderDetails table's isComplete are all true for that supplierOrder ID. Please see the attachment for the tables. I have tried myself with this query but I think it could be a better way or more efficient.
SELECT 1
FROM supplierOrder so
inner JOIN supplierOrderdetails sod
ON so.id = sod.supplierOrderID
WHERE so.id = 1
AND sod.isComplete= 1
This should work, I maynot have correct table names but this should work if u change it
UPDATE suplierorder
SET iscomplete = 'true'
WHERE id IN (SELECT suplierorderid
FROM (SELECT suplierorderid,
--case statement to set to 0 if complete and 1 if not complete (i.e any other value null or false)
Sum(CASE
WHEN iscomplete = 'true' THEN 0
ELSE 1
END) AS complete
FROM suplierorderdetails
--make sure we only update the new ones and makes sure that your select records are limited to Just not complete records, so if your tables grow this will make your update statement doesn't take a lot of time
WHERE suplierorderid IN (SELECT id
FROM suplierorder
WHERE iscomplete IS NULL)
--I am grouping on suplierorderid so that we can add all the iscomplete status of each suplierorderid column
GROUP BY suplierorderid) A
--now that the inner query outputs suplierorderid and complete status which will be 0 if everything is complete we are writing below condition
WHERE complete = 0)
All we need is to find supplierOrderID where MIN(isComplete)=1. So it means that ALL isComplete=TRUE
UPDATE supplierOrder SET isComplete=1
WHERE id in
(
SELECT supplierOrderID
FROM supplierOrderdetails
GROUP BY supplierOrderID
HAVING MIN(CAST(isComplete as Int))=1
)
AND
(
(isComplete is NULL ) OR (isComplete = 0)
)
SQLFiddle demo
PS: Since isComplete is a BIT type field you can't use MIN(isComplete) but you can use MIN(CAST(isComplete as Int))