Update table with if statement PL/SQL - oracle

I am trying to do something like this but am having trouble putting it into oracle coding.
BEGIN
IF ((SELECT complete_date FROM task_table WHERE task_id = 1) IS NULL)
THEN
UPDATE task_table SET complete_date = //somedate WHERE task_id = 1;
ELSE
UPDATE task_table SET complete_date = NULL;
END IF;
END;
But this does not work. I also tried
IF EXISTS(SELECT complete_date FROM task_table WHERE task_id = 1)
with no luck.

I don't think you'd need the procedural block if your actual logic is like the one above.
Assuming this is your task:
"if the value of complete_date for id
1 is NULL, update it with XXX. Otherwise set it to null".
You could just run ...
Update task_table
set complete_date = nvl2(complete_date,NULL, <**your date**>)
where task_id = 1;
This will only update those records where the complete_date is null with your new date.

What is the intention of this part?
IF ((SELECT complete_date FROM task_table WHERE task_id = 1) IS NULL)
Is it to find if there are rows where complete_date is null and task_id = 1?
Or is it to check if there are no rows where task_id = 1?

Related

Oracle - Updating table based on field from another table

I have a Task table and a Project table. I'm trying to update the Percent Complete field in the Project table with the value of the Percent Complete field from the Tasks table. But I only want to update the field when the sequence code from the Task table is equal to 1. My failed attempt looks like this:
UPDATE inv_projects prj
SET prj.percent_complete = (SELECT NVL(tsk.prpctcomplete, 0)
FROM prtask tsk
WHERE tsk.prprojectid = prj.prid)
WHERE (SELECT tsk.prwbssequence
FROM prtask tsk
WHERE prj.prid = tsk.prprojectid) = 1;
I'm getting the error:
Error starting at line : 1 in command -
...
Error report -
ORA-01427: single-row subquery returns more than one row
I'm not quite sure what's going wrong.
Presumably, you want the sequence filtering in the subquery, like so
UPDATE inv_projects prj
SET prj.percent_complete = (
SELECT NVL(tsk.prpctcomplete, 0)
FROM prtask tsk
WHERE tsk.prprojectid = prj.prid AND sk.prwbssequence = 1
)
This assumes that (prprojectid, prwbssequence) is unique in the task table, which seems consistent with your problem statement.
If there are projects without a task of sequence 1, and you don't want to update them, then use exists:
UPDATE inv_projects prj
SET prj.percent_complete = (
SELECT NVL(tsk.prpctcomplete, 0)
FROM prtask tsk
WHERE tsk.prprojectid = prj.prid AND sk.prwbssequence = 1
)
WHERE EXISTS (
SELECT 1
FROM prtask tsk
WHERE tsk.prprojectid = prj.prid AND sk.prwbssequence = 1
)
Or maybe your intent is to set the completion percent to 0 in this case; if so, move NVL() outside of the subquery:
UPDATE inv_projects prj
SET prj.percent_complete = NVL(
(
SELECT tsk.prpctcomplete
FROM prtask tsk
WHERE tsk.prprojectid = prj.prid AND sk.prwbssequence = 1
),
0
)

Unexpected NULL in multi-column correlated update

I want to run a multi-column correlated update of this kind:
UPDATE t1 t1_alias
SET (table_name, tablespace_name) = (
SELECT table_name, tablespace_name
FROM t2 t2_alias
WHERE t1_alias.table_name = t2_alias.table_name
);
But my attempt:
update customer up
set (customer_name, account, active) = (
select tmp.name, tmp.account, case when tmp.active = 'Yes' then 1 else 0 end
from customer_temp tmp
where up.agent = substr(tmp.agent, -4) and up.customer_code = tmp.code
);
... throws:
ORA-01407: cannot update ("FOO"."CUSTOMER"."CUSTOMER_NAME") to NULL
The source table customer_temp has no null values so I must be getting matches wrong. What is my error or misconception?
Presumably, there are some rows in the target table that have no match in the subquery.
You can avoid this with by adding an exists condition that filters out "unmatched" rows:
update customer up
set (customer_name, account, active) = (
select tmp.name, tmp.account, case when tmp.active = 'Yes' then 1 else 0 end
from customer_temp tmp
where up.agent = substr(tmp.agent, -4) and up.customer_code = tmp.code
)
where exists (
select 1
from customer_temp tmp
where up.agent = substr(tmp.agent, -4) and up.customer_code = tmp.code
);

Oracle Update statement with if conditions

I'm trying to merge three update statements into one.
"UPDATE DOT_WORKS SET START_DATE = :StartDate WHERE ID = :WorksId and END_DATE IS NULL;"
"UPDATE DOT_WORKS SET WORKS_TYPE = :WorksType WHERE ID = WorksId and WORKS_GROUP = :WorksGroup;"
"UPDATE DOT_WORKS SET WORKS_CONNECTION = :WorksConn WHERE ID = WorksId and WORKS_PLACE = :WorksPlace;"
I'm wondering whether there is a way to do that.
The reason why I'm trying to do so is to save the calls to database. It's more efficient to call db once instead of three.
Thanks!
UPDATE DOT_WORKS
SET START_DATE = case when END_DATE IS NULL then :StartDate else START_DATE end,
WORKS_TYPE = case when WORKS_GROUP = :WorksGroup then :WorksType else WORKS_TYPE end,
WORKS_CONNECTION = case when WORKS_PLACE = :WorksPlace then :WorksConn else WORKS_CONNECTION end
WHERE ID = :WorksId
and
(
END_DATE IS NULL OR
WORKS_GROUP = :WorksGroup OR
WORKS_PLACE = :WorksPlace
)

If condition with select query in oracle

How to Use IF Condition with Select Query in Oracle. Please suggest
IF (SELECT ptr_forecast_dt from ptr_details WHERE ptr_line_id = prmptr_line_id AND ptr_actual_dt IS NULL) IS NOT NULL THEN
SELECT ptr_forecast_dt INTO Forcast_dt from ptr_details WHERE ptr_line_id = prmptr_line_id AND ptr_actual_dt IS NULL;
END IF;
You can simply add another condition in the WHERE clause, as below:
SELECT ptr_forecast_dt
INTO Forcast_dt
FROM ptr_details
WHERE ptr_line_id = prmptr_line_id
AND ptr_actual_dt IS NULL
AND ptr_forecast_dt IS NOT NULL;
If you want to insert an alternate value if ptr_forecast_dt is NULL, then you can use the NVL function, as below:
SELECT NVL(ptr_forecast_dt, TO_DATE('01/01/2014', 'MM/DD/YYYY'))
INTO Forcast_dt
FROM ptr_details
WHERE ptr_line_id = prmptr_line_id
AND ptr_actual_dt IS NULL;

Trigger on one table field works for all table fields

I have a trigger which is for a few fields in a table. But for some reason, if another field is changed (which is not defined in trigger) then it still fires.
CREATE OR REPLACE TRIGGER INTEGRATION_EMPLOYMENT
AFTER UPDATE OF start_day_of_employment, end_of_employment ON hr_employment_data
FOR EACH ROW
DECLARE
BEGIN
IF UPDATING THEN
MERGE INTO ad_integration intg USING dual ON (intg.user_id = :NEW.user_id AND intg.integrated = 'NO')
WHEN MATCHED THEN
UPDATE SET
intg.start_day_of_employment = decode(:NEW.start_day_of_employment, NULL, ' ', :NEW.start_day_of_employment),
intg.end_of_employment = decode(:NEW.end_of_employment, NULL, ' ', :NEW.end_of_employment),
intg.manager_status = :NEW.manager_status,
intg.pid = (SELECT pid FROM arc.user_info WHERE user_id = :NEW.user_id),
intg.network_access_start_date = (SELECT network_access_start_date FROM hr_extension_data WHERE user_id = :NEW.user_id)
WHEN NOT MATCHED THEN
INSERT (intg.user_id, intg.start_day_of_employment, intg.end_of_employment, intg.manager_status, intg.pid, intg.network_access_start_date
VALUES (:NEW.user_id, :NEW.start_day_of_employment, :NEW.end_of_employment, :NEW.manager_status, (SELECT pid FROM arc.user_info WHERE user_id = :NEW.user_id), (SELECT network_access_start_date FROM hr_extension_data WHERE user_id = :NEW.user_id));
END IF;
END HR_ADINTEGRATION_EMPLOYMENT;
Is it because of using DUAL or something am I missing?
Cheers! :-)
If you want to leave the structure as is and only process the trigger when the specifc fields change, then just do a quick compare (new code lines 7 and 8):
CREATE OR REPLACE TRIGGER INTEGRATION_EMPLOYMENT
AFTER UPDATE OF start_day_of_employment, end_of_employment ON hr_employment_data
FOR EACH ROW
DECLARE
BEGIN
IF UPDATING
AND (:NEW.start_day_of_employment <> :OLD.start_day_of_employment
OR :NEW.end_of_employment <> :OLD.end_of_employment) THEN
MERGE INTO ad_integration intg USING dual ON (intg.user_id = :NEW.user_id AND intg.integrated = 'NO')
WHEN MATCHED THEN
UPDATE SET
intg.start_day_of_employment = decode(:NEW.start_day_of_employment, NULL, ' ', :NEW.start_day_of_employment),
intg.end_of_employment = decode(:NEW.end_of_employment, NULL, ' ', :NEW.end_of_employment),
intg.manager_status = :NEW.manager_status,
intg.pid = (SELECT pid FROM arc.user_info WHERE user_id = :NEW.user_id),
intg.network_access_start_date = (SELECT network_access_start_date FROM hr_extension_data WHERE user_id = :NEW.user_id)
WHEN NOT MATCHED THEN
INSERT (intg.user_id, intg.start_day_of_employment, intg.end_of_employment, intg.manager_status, intg.pid, intg.network_access_start_date
VALUES (:NEW.user_id, :NEW.start_day_of_employment, :NEW.end_of_employment, :NEW.manager_status, (SELECT pid FROM arc.user_info WHERE user_id = :NEW.user_id), (SELECT network_access_start_date FROM hr_extension_data WHERE user_id = :NEW.user_id));
END IF;
END HR_ADINTEGRATION_EMPLOYMENT;

Resources