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

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.

Related

SQL command not properly ended in Python OracleSQL

I'm having some trouble with SQL code that works when I run it in DBeaver, but when I execute it with cx_Oracle it comes up with the error of:
cx_Oracle.DatabaseError: ORA-00933: SQL command not properly ended
The python code is good, but I'm not much of a SQL programmer, so maybe someone can look to see if there is any obvious coding errors. It's just weird that the code works in DBeaver but not with cx_Oracle.
Here is the code:
WITH MDVC_LP_HEADER_DATA AS
(select
distinct trunc(lh.start_time) as "Consumption Date",
md.client_co_account_id as "NMI",
md.MR_MDVC_NUMBER as "Meter",
lh.mdvc_id,
lh.header_id,
lh.lp_attribute_id,
lh.entry_date,
lh.rec_status,
cm.register_id as "Register",
nvl(st.crm_register_id, st.register_id) as "Register_ID",
st.stream_id as "Stream"
from WACSMDMS.mdvc_lp_header lh,
WACSMDMS.metering_device md,
WACSMDMS.lp_attribute_config c,
WACSMDMS.ozwave_register_channel_map cm,
WACSMDMS.nem12_subs_members st
where 1=1
and md.mdvc_id = lh.mdvc_id
and lh.entry_date between to_date('26-JUL-2021') + 1 and to_date('2-AUG-2021')+1
and lh.rec_status in ('VFD', 'VDD')
and lh.lp_attribute_id = c.lp_attribute_id
and cm.channel_id = c.channel_id
and st.nmi = md.client_co_account_id
and st.meter_number = md.MR_MDVC_NUMBER
and st.register_id = cm.register_id
and st.stream_id != 'X'
and st.subscriber_acr = 'EVERGY'
),
mdvc_lp_dta as
(
select
distinct
lh."Consumption Date" as "Consumption Date",
lh."NMI" as "NMI",
lh."Meter" as "Meter",
lh.mdvc_id as "MDVC_ID",
lh.lp_attribute_id,
lh.rec_status,
lp.comments as "Reason Description",
lp.DATA_ID, lp.STATUS, lp.reason_code, lh."Register", lh."Stream" , lh."Register_ID"
from WACSMDMS.mdvc_lp_data lp, WACSMDMS.MDVC_LP_HEADER_DATA lh
where 1=1
and lh.mdvc_id = lp.mdvc_id
and lh.lp_attribute_id = lp.lp_attribute_id
and lh.header_id = lp.header_id
and lp.end_time > lh.entry_date -1
and lp.end_time <= lh.entry_date
),
base as
(select
lp."Consumption Date",
lp."NMI",
lp."Meter",
lp."MDVC_ID",
lp."Reason Description",
lp.DATA_ID,
lp.STATUS,
lp.reason_code,
NVL(a.GUI_DISPLAY_DESC,a.description) subs_type,
CASE
WHEN orcd.reason_code IS NOT NULL THEN orcd.reason_code||' ('||orcd.reason_description|| ')'
ELSE NULL
END AS "Reason Code",
CASE
WHEN lp.DATA_ID = 1 AND lp.STATUS IS NOT NULL THEN 'Substituted'
ELSE
CASE WHEN lp.DATA_ID = 0 THEN 'Actual'
ELSE NVL(LDS.GUI_DISPLAY_DESC,LDS.DESCRIPTION)
END
END AS read_data_id,
NVL(a.GUI_DISPLAY_DESC,a.description) AS read_data_status,
lp.rec_status as rec_status2,
lds.dataid_status_ind,
a.dataid_status_ind dataid_status_ind2, lp."Register", lp."Stream", lp."Register_ID"
from
WACSMDMS.mdvc_lp_dta lp,
WACSMDMS.lp_data_status a,
WACSMDMS.lp_data_status lds,
WACSMDMS.ozwave_reason_code_dim orcd
where 1=1
and a.mr_gateway_id IS NULL
AND a.dataid_status_ind(+) = 'S'
AND a.file_data_status_id(+) = lp.status
AND lp.data_id = lds.file_data_status_id (+)
AND lds.mr_gateway_id (+) IS NULL
AND lds.dataid_status_ind (+) = 'D'
and lp.reason_code =orcd.reason_code (+)
)
select "Consumption Date","NMI","Meter","Register","MDVC_ID",
( case when subs_type is null and read_data_id = 'Churn Substitution' and
read_data_status is null then 'Type 19 Zero' else subs_type end ) as "Substitution Type",
"Reason Code","Reason Description",read_data_id as "Data Quality", "Stream", "Register_ID"
from base
where 1=1
and ( ( base.read_data_id = 'Churn Substitution' and base.read_data_status is null ) or
( base.rec_status2 = 'VDD' and base.subs_type is not null and base.read_data_id <> 'Final Substitution' ))
order by 1,2,3,4;
Query itself looks OK (as you said, it works in DBeaver). Maybe it is that Python doesn't "like" closing statement terminator (semi-colon at the very end of the query) - try to remove it.
Apart from that, I'd suggest you not to rely on Oracle's guessing date format. Instead of TO_DATE ('26-JUL-2021'), use TO_DATE ('26-JUL-2021', 'DD-MON-YYYY') (i.e. always provide appropriate format mask). Note that MON can be tricky if database doesn't speak English (for example, it would fail in my database which speaks Croatian) so - it is safer to use e.g. TO_DATE ('26.07.2021', 'DD.MM.YYYY')

ORACLE(TOAD) CASE with multiple conditions for different updates

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

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.

Converting the sybase stuff function in to oracle

Sybase query :
UPDATE #horizCallSign SET
effDaysZ = STUFF( effDaysZ, csd.day+shift1, 1, '1')
FROM #callSignTbl csd
WHERE csd.legId1 = #horizCallSign.legId1
AND csd.legId2 = #horizCallSign.legId2
AND day = 28
Oracle Query :
UPDATE TEMP_HORIZ_CALL_SIGN
SET eff_Days_Z = REPLACE( eff_days_Z,csd.day+shift1, '1')
FROM temp_call_sign_table1 csd
WHERE csd.leg_Id1 = temp_horiz_Call_Sign.leg_Id1
AND csd.leg_Id2 = horiz_Call_Sign.leg_Id2
AND day = 28
In Oracle, we have changed the column names with having "_" in them.
temp_call_sign_table1 and TEMP_HORIZ_CALL_SIGN are global temporary tables
created for Oracle in place of sybase temp tables with on commit preserve
rows.
We are converting sybase DB to Oracle DB. When I execute the above query in oracle it says QL Error: ORA-00933: SQL command not properly ended.
Please help.
There was an issue with your table name on line 5, this is easily avoided by using aliases.
Also, you can't use FROM in Oracle without a SELECT. Thus a sub-query must be used in this instance. For example...
UPDATE TEMP_HORIZ_CALL_SIGN hcs
SET eff_Days_Z =
(SELECT
REPLACE(eff_days_Z,csd.day+shift1, '1')
FROM temp_call_sign_table1 csd
WHERE csd.leg_Id1 = hcs.leg_Id1
AND csd.leg_Id2 = hcs.leg_Id2
AND day = 28)
(Not tested)
Your are off on your aliasing. Also, consider using INNER JOINS instead.
UPDATE THCS
SET eff_Days_Z = REPLACE( eff_days_Z,csd.day+shift1, '1')
FROM temp_call_sign_table1 csd , TEMP_HORIZ_CALL_SIGN THCS, horiz_Call_Sign HCS
WHERE csd.leg_Id1 = THCS.leg_Id1
AND csd.leg_Id2 = HCS.leg_Id2
AND day = 28
In Oracle, You can use MERGE INTO.
MERGE INTO temp_horiz_call_sign m
using (SELECT leg_id1,
leg_id2,
eff_days_z,
day + shift1 plushift1
FROM temp_call_sign_table1
WHERE day = 28) r
ON ( r.leg_id1 = m.leg_id1
AND r.leg_id2 = m.leg_id2 )
WHEN matched THEN
UPDATE SET m.eff_days_z = Replace(m.eff_days_z, r.plushift1, '1');

SQL Batch Update error - New request is not allowed to start because it should come with valid transaction descriptor

I am running microsoft sql 2008 and jdbc driver 3.0 and am getting this error on a batch SQL update
"New request is not allowed to start because it should come with valid transaction descriptor"
To debug I've reduced the batch size down to just one statement, but it still errors. Here it is
IF EXISTS (SELECT * FROM StaffDetail WHERE PsnID = 'GC91')
UPDATE staffdetail
SET psnid = 'GC91',
servicegroup = '41B001',
discipline = 'IT',
dob = '1967-09-28',
ghdstartdate = '2008-12-15',
yearsexperience = '11 to 20 years',
classification = 'Admin Officer 1'
WHERE psnid = 'GC91'
ELSE
INSERT INTO staffdetail
(psnid,
servicegroup,
discipline,
dob,
ghdstartdate,
yearsexperience,
classification)
VALUES ('GC91',
'41B001',
'IT',
'1967-09-28',
'2008-12-15',
'11 to 20 years',
'Admin Officer 1')
Why does it error? I've googled this and only found references to a bug in SQL 2005 not 2008.
Is there any way I can change the connection string I use to connect or change the SQL statements I use in the batch to try and avoid this error?
Try changing your SQL to this:
UPDATE StaffDetail SET PsnID = 'GC91',ServiceGroup = '41B001',Discipline = 'IT',DOB = '1967-09-28',GHDStartDate = '2008-12-15',YearsExperience = '11 to 20 years',Classification = 'Admin Officer 1' WHERE PsnID = 'GC91';
INSERT INTO StaffDetail (PsnID,ServiceGroup,Discipline,DOB,GHDStartDate,YearsExperience,Classification)
SELECT 'GC91','41B001','IT','1967-09-28','2008-12-15','11 to 20 years','Admin Officer 1'
WHERE NOT EXISTS (SELECT * FROM StaffDetail WHERE PsnID = 'GC91')
can you put the above code as Stored Procedure definition and pass thru using con.prepareStatement ?
A late update, in case others find my findings useful...
I have had this problem a lot recently. Re-architeching the query to either use CTE or Table Variables has often resolved it, but believe that ultimately, as noted at http://computer-aaaargh.blogspot.co.za/2012/12/weird-cause-of-msg-3989-new-request-is.html , it has to do with the underlying data. Look at your joins and try and change what you are fetching back from the underlying data - in this case only the one statement (Try SELECT 1 FROM StaffDetail WHERE PsnID = 'GC91') or use another script in the exist just as a form of elimination.
You can MERGE instead which removes the IF and ELSE which makes it really one statement
MERGE INTO staffdetail AS TARGET
USING (VALUES ('GC91',
'41B001',
'IT',
'1967-09-28',
'2008-12-15',
'11 to 20 years',
'Admin Officer 1')) AS SOURCE (psnid, servicegroup, discipline, dob,
ghdstartdate, yearsexperience, classification)
ON TARGET.psnid = SOURCE.psnid
WHEN MATCHED THEN
UPDATE SET servicegroup = SOURCE.servicegroup,
discipline = SOURCE.discipline,
dob = SOURCE.dob,
ghdstartdate = SOURCE.ghdstartdate,
yearsexperience = SOURCE.yearsexperience,
classification = SOURCE.classification
WHEN NOT MATCHED BY TARGET THEN
INSERT (psnid,
servicegroup,
discipline,
dob,
ghdstartdate,
yearsexperience,
classification)
VALUES ('GC91',
'41B001',
'IT',
'1967-09-28',
'2008-12-15',
'11 to 20 years',
'Admin Officer 1')