ORACLE(TOAD) CASE with multiple conditions for different updates - sql

I need to update qualifications in a Oracle DB, I am running into a problem where my script errors.
I would usually create a few smaller update statements to get the job done.
However I thought it would be better to do one query, this is simple but my background is mostly on T-SQL and mySQL not Oracle.
So help would be appreciated.
My Statement.
--ALTER SESSION TO CHANGE DT--
alter session set nls_date_format = 'DD/MM/YYYY HH24:MI:SS';
--Update
Update Qualifications_t
Set (COMMENTS = 'Task'),
(Expiry_DTS = CASE Expiry_DTS
When cd = '1'
Then Expiry_DTS = '31/12/2016 23:59:00'
When cd = '2'
Then Expiry_DTS = '01/07/2019 23:59:00'
When cd = '3'
Then Expiry_DTS = '31/12/1999 23:59:00'
When cd = '4'
Then Expiry_DTS = '31/08/2021 23:59:00'
When cd = '5'
Then Expiry_DTS = '17/06/2021 23:59:00')
END
Where EXPIRY_DTS IS NULL;
--SELECT
Select *
from QUALIFICATIONS_T
where COMMENTS = 'Task';
Error at line 5
ORA-00905: missing keyword
Yes, I googled it but couldn't figure it out.

Remove the parentheses around the update assignments.
Then: it's not clear what you mean by the case expression. Perhaps this:
update qualifications_t
set comments = 'task',
expiry_dts = case when cd = '1' then to_date('31/12/2016 23:59:00',
'dd/mm/yyyy hh24:mi:ss')
when cd = '2' then to_date(....)
(etc.)
end
where expiry_dts is null
;
Notice the structure of a case expression. The name of the column you are updating doesn't belong after the keyword case, and the case expression "returns" values directly, not through assignments. There should be only one assignment ("equal sign"); the case expression is evaluated and returns a single value, used for update.
Note also the proper way to represent date values (assuming the column data type is date, as it should be; if it isn't, you should fix that first).

Related

GETTING ERROR-- ORA-00936:MISSING EXPRESSION for below query please help on this

SELECT CASE (SELECT Count(1)
FROM wf_item_activity_statuses_v t
WHERE t.activity_label IN ('WAITING_DISB_REQ',
'LOG_DDE',
'LOG_SENDBACK_DDE')
AND t.item_key IN(
SELECT r.i_item_key
FROM wf_t_item_xref r
WHERE r.sz_appl_uniqueid = '20400000988')
)
WHEN 0 THEN
(
delete
from t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_item_key = '648197'
AND p.i_document_srno = '27' )
WHEN 1 THEN
(
DELETE
FROM t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_document_srno = '28' )
ELSE NULL
END
FROM dual;
You need to recreate your query and make sure to follow the flow of the clauses properly, please check the next two links to get a better understanding :
[ORA-00936: missing expression tips]
How do I address this ORA-00936 error?
Answer: The Oracle oerr utility notes this about the ORA-00936 error:
ORA-00936 missing expression
Cause: A required part of a clause or expression has been omitted. For example, a SELECT statement may have been entered without a list of columns or expressions or with an incomplete expression. This message is also issued in cases where a reserved word is misused, as in SELECT TABLE.
Action: Check the statement syntax and specify the missing component.
The ORA-00936 happens most frequently:
1 - When you forget list of the column names in your SELECT statement.
2. When you omit the FROM clause of the SQL statement.
ora-00936-missing-expression
I hope this can help you.
You cannot use a simple select query like this. You have to use a PL/SQL block like below -
DECLARE NUM_CNT NUMBER := 0;
BEGIN
SELECT Count(1)
INTO NUM_CNT
FROM wf_item_activity_statuses_v t
WHERE t.activity_label IN ('WAITING_DISB_REQ',
'LOG_DDE',
'LOG_SENDBACK_DDE')
AND t.item_key IN(SELECT r.i_item_key
FROM wf_t_item_xref r
WHERE r.sz_appl_uniqueid = '20400000988');
IF NUM_CNT = 0 THEN
delete
from t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_item_key = '648197'
AND p.i_document_srno = '27';
ELSIF NUM_CNT = 1 THEN
DELETE
FROM t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_document_srno = '28' )
END IF;
END;

How can I retrieve an updated script in the oracle database?

How can I retrieve an updated script in the oracle database?
An incorrect script was run in the oracle database. I want to get this script back. how can I do that? The script is as follows.
--52 record
update cons.paymentplan_detail det set det.payment_date = to_char(ADD_MONTHS(to_Date (det.payment_date, 'YYYYMMDD'),3),'YYYYMMDD')
where det.oid in (select det.oid
from cons.instalment_instalment_loan ins,
cons.paymentplan_detail det,
cons.paymentplan_def def,
(select ins.loans_reference_no,min(det.payment_date) as payment_date
from cons.instalment_instalment_loan ins,
cons.paymentplan_detail det,
cons.paymentplan_def def
where ins.loan_state in ('OPEN', 'BLOCKED')
and ins.status = '1'
and def.status = '1'
and det.status = '1'
and ins.payment_plan_oid = det.payment_plan_oid
and det.plan_detail_status in ('NO','LT')
and ins.OID='251pfek38q43fg00'
and def.oid = det.payment_plan_oid
and def.payment_plan_status = 'GR'
and def.credit_oid = ins.oid
group by ins.loans_reference_no) t
where ins.loan_state in ('OPEN', 'BLOCKED')
and ins.status = '1'
and def.status = '1'
and det.status = '1'
and ins.payment_plan_oid = det.payment_plan_oid
and det.plan_detail_status in ('NO')
and ins.OID='251pfek38q43fg00'
and def.oid = det.payment_plan_oid
and def.payment_plan_status = 'GR'
and def.credit_oid = ins.oid
and t.loans_reference_no = ins.loans_reference_no
group by det.oid);
If you haven't COMMITted the data then use ROLLBACK.
Otherwise, your solution could be as simple as running the same query but subtracting 3 months:
update cons.paymentplan_detail det
set det.payment_date = to_char(
ADD_MONTHS(
to_Date (det.payment_date, 'YYYYMMDD'),
-3 -- Changed from +3 to -3
),
'YYYYMMDD'
)
where ...
If that won't work and you have COMMITted the data and the database has flashback activated then you can use a flashback query to find the old data from before the UPDATE.
If all that fails, then you can look and see if the database has a recent backup you can restore from.

Difference between querying from Impala and querying from Hive?

I have a Hive source table which contains:
select count(*) from dev_lkr_send.pz_send_param_ano;
--25283 lines
I am trying to get all of the table lines and put them into a dataframe using Spark2-Scala. I did the following:
val dfMet = spark.sql(s"""SELECT
CD_ANOMALIE,
CD_FAMILLE,
libelle AS LIB_ANOMALIE,
to_date(substr(MAJ_DATE, 1, 19), 'YYYY-MM-DD HH24:MI:SS') AS DT_MAJ,
CLASSIFICATION,
NB_REJEUX,
case when indic_cd_erreur = 'O' then 1 else 0 end AS TOP_INDIC_CD_ERREUR,
case when invalidation_coordonnee = 'O' then 1 else 0 end AS TOP_COORDONNEE_INVALIDE,
case when typ_mvt = 'S' then 1 else 0 end AS TOP_SUPP,
case when typ_mvt = 'S' then to_date(substr(dt_capt, 1, 19), 'YYYY-MM-DD HH24:MI:SS') else null end AS DT_SUPP
FROM ${use_database}.pz_send_param_ano""")
When I execute dfMet.count() it returns: 46314
Any ideas about the source of the difference?
EDIT1:
Trying the same query from Hive returns the same value as in the dataframe (I was querying from Impala UI before).
Someone can explain the difference please? I am working on Hue4.
A potential source of difference is your Hive query is returning the result from the metastore which is out of date rather than running a fresh count against the table.
If you have hive.compute.query.using.stats set to true and the table has stats computed then it will be returning the result from the metastore. If this is the case then it could be your stats are out of date and you need to recompute them.

Incorrect syntax near 'End' , not letting run the query nor create procedure

Not letting me create the procedure, nor not letting run this query please help.
It's not letting run the query .. this is just a section of query
You had a few things wrong, you didnt need the parens, you were missing an End Statement, and your indents made it hard to read, and you are missing your FROM statement, so I put FROM and added tableName you need to fill this in.
create proc [dbo].[a_test]
as
begin
SELECT top 10
file_ty = '5',
cno= rtrim(ltrim(adm.AccountNumber)),
Column3='',
Column4='',
Admit_Date =
CASE
WHEN RegistrationType_MisRegTypeID <>'IN'
THEN ''
ELSE CONVERT(varchar(10),replace(convert(varchar(10),adm.AdmitDateTime,101),'/ ',''))
END,
Point_Of_Origin =
CASE
WHEN RegistrationType_MisRegTypeID='IN' then
CASE
WHEN AdmitSource='CIR' then '2'
WHEN AdmitSource='BSH' then '2'
ELSE ''
END
END
FROM dbo.TableName
END

SQL Update when not null

I'm trying to set a column in the fabcon table only if the original column is null.
This is the code I've already tried.
UPDATE dbo.fabcon
SET ext = COALESCE(ext, ( SELECT CASE WHEN [<3] IS NOT NULL THEN '3' END AS extent
FROM dbo.spreadsheetData ))
This is the error I'm getting:
Sub-query returned more than 1 value. This is not permitted when the sub-query follows =, !=, <, <= , >, >= or when the sub-query is used as an expression.
Can anyone see where I've gone wrong?
Thanks. :)
EDIT: the two tables fabcon and spreadsheetData are linked by a column called main1
EDIT2: I've updated the query to this:
UPDATE dbo.fabcon
SET ext = (SELECT CASE WHEN [<3] IS NOT NULL THEN '3' END
FROM dbo.spreadsheetData ssd
WHERE ssd.id = fabcon.id
)
WHERE ext IS NULL;
However, its still failing with the same error.
You need a link between the table fabcon and spreadsheetData. Assuming it is called id:
UPDATE dbo.fabcon
SET ext = (SELECT CASE WHEN [<3] IS NOT NULL THEN '3' END)
FROM dbo.spreadsheetData ssd
WHERE ssd.id = fabcon.id
)
WHERE ext IS NULL;
Note that I removed the coalesce() and replaced it with a where clause for the update. This prevents the query from updating rows unnecessarily (with unchanged values).
DECLARE #PAth INT
Select #path = COALESCE(ext,'')+[<3]+';' FROM dbo.spreadsheetData
UPDATE dbo.fabcon
SET ext = CASE WHEN #PAth IS NOT NULL
THEN '3' ELSE ''
END AS Extent
FROM dbo.fabcon f WHERE f.id = #path
may be this works i think
This should work for you. Assuming I have understood your original query correctly
UPDATE dbo.fabcon
SET
ext = ssd.[column to insert data from]
FROM
dbo.spreadsheetData ssd
WHERE
ext IS NULL
AND
fabcon.id = ssd.id
This assumes the id in the ssd table is the id from the fabcon table. Otherwise just change the id matching based on your column specification
UPDATE dbo.fabcon
SET ext = (SELECT TOP 1 CASE WHEN [<3] IS NOT NULL THEN '3' END
FROM dbo.spreadsheetData ssd
WHERE ssd.main1 = fabcon.main1
ORDER BY 1
)
WHERE ext IS NULL;
with the 2 tables related via "main1" (as now indicated) and an arbitrary "TOP 1" thrown in to avoid the error, this might work.
but: the best way to get an answer is to provide some sample data and an expected result