Getting Error with Date Format in To_Char - oracle

I am getting error in the second script. Please explain why i am getting error in the second script.
select count(*) from LCL_SHR_IncidentIntegrationInt where
externalsystem = 'IPSOFT'
and (to_char(sysdate,'YYYYMMDDHH24MISS')-to_char(fn_adjusted_date(CREATE_DATE),'YYYYMMDDHH24MISS')) > 180;
O/P : 122797
select count(*) from LCL_SHR_IncidentIntegrationInt where
externalsystem = 'IPSOFT'
and (to_char(sysdate,'DD-MM-YYYY HH24:MI:SS')-to_char(fn_adjusted_date(CREATE_DATE),'DD-MM-YYYY HH24:MI:SS')) > 180;
O/P : ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.

The first query works because Oracle is able to implicitly cast the characters as number and compare with 180. The other one doesn't because the : and - cannot be implicitly cast to number.
You should use date and time functions for such cases like timestampdiff or datediff. More functions here - https://docs.oracle.com/cd/E17952_01/refman-5.1-en/date-and-time-functions.html

Related

ORA-01722: invalid number 01722. 00000 - "invalid number" *Cause: The specified number was invalid. *Action: Specify a valid number

I am new to Oracle SQL Developer, and today while running this
select r.id, r.date, it.group, it.comment, it.item, it.remark, r.summary,
substr (it.remark, instr(it.remark,'ABC')+8,7 ) as label1,
cast(substr (it.remark, instr(it.remark,'-')+1,3 ) as integer) as label2
from it_table it
inner join sp_table sp on sp.id = substr (it.remark, instr(it.remark,'ABC')+8,7 ) and sp.label_id = cast(substr (it.remark, instr(it.remark,'-')+1,3 ) as integer)
inner join sq_table sq on sq.id = sp.id
where it.date > '01-jan-2020' and it.remark like '%ABC%' and it.group= 'O'
order by sp.id, it.id;
it caught the error:
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.
I think the problem lies with the extraction as in row 3 (cast(substr (it.remark, instr(it.remark,'-')+1,3 ) as integer)), where I need to convert a string into a number using cast.
According to doc, the error occurs when an attempt is made to convert a character string into a number, and the string cannot be converted into a valid number.
So, I tried replacing:
cast(substr (it.remark, instr(it.remark,'-')+1,3 ) as integer)
with
to_number(substr (it.remark, instr(it.remark,'-')+1,3 ))
and even tried to_char but didn't work. However, the original script seems to work fine in sandbox database. I am wondering why this is happening. Any help is greatly appreciated.
Update:
Sample data it:
ID DATE NAME GROUP REMARK COMMENT ...
100 20-10-08 AABC X ACS LOCATION 1 - ABC IDD x105213-1
​101 20-10-08 AxB Y MN LOCATION 8 - ABC IDD x105244-2
...
Sample data sp:
ID DATE NAME GROUP label_id
105213 20-10-08 AABC X 1
​105244 20-10-08 AxB Y 2
...
It turns out that the error was caused by having 2 - in remark which lead to ambiguity and I just need the second one.
New question then:
How do I extract the last - in the value to join with another value in the other column?
Use cast with default null on conversion error to avoid exception and investigate the cause of the failed conversion.
Example
with dt as
(select '001' remark from dual union all
select ' 2' from dual union all
select 'OMG' from dual)
select substr(remark,1,3) txt,
cast (substr(remark,1,3) as INT default null on conversion error) num
from dt;
TXT NUM
--- ----------
001 1
2 2
OMG

Try to convert Time to Sec in Oracle SQL

I am trying to convert Time to Sec but whatever I try I get error message.
The following query is what I done so far
SELECT
SUM(TIME_TO_SEC(mi.Time)),
uti.Date_
FROM
users ui
LEFT JOIN project_users pui
ON(ui.UserID = pui.UserID)
LEFT JOIN user_timesheets uti
ON(ui.UserID = uti.user_id)
LEFT JOIN moments mi
ON(uti.UserTimesheetsID = mi.UserTimesheetsID)
WHERE
uti.user_id = 1 AND mi.Time != ''
AND
EXTRACT(MONTH FROM uti.Date_) = '2020-01-21'
AND
EXTRACT(YEAR FROM uti.Date_) = '2020-01-21'
AND
mi.AtestStatus = 1
GROUP BY
uti.Date_
HAVING SUM(SELECT(TIME_TO_SEC(mi.Time))) > 28800;
I get error
ORA-00936: missing expression
00936. 00000 - "missing expression"
*Cause:
*Action:
Error at Line: 74 Column: 36
I am not sure what to use here to convert, but so far I try to use TO_CHAR and CAST
The reference link is here
REFERENCE
You refer TIME_TO_SEC function from MySQL documentation though question is marked with oracle tag. Use extract(second ...) or google oracle extract epoch equivalent, depending on what you want.
Also the expressions EXTRACT(MONTH FROM uti.Date_) = '2020-01-21' and EXTRACT(YEAR... look suspicious, returned values definitely are not of form 'YYYY-MM-DD'.

Oracle - CAST(row_number) query

SELECT NOABSEN,TANGGAL,JAM,
'Jam' + CAST(ROW_NUMBER() OVER (PARTITION BY NOABSEN ORDER BY NOABSEN desc) as VARCHAR(20))
as ColumnsSequence
From HRD_ABS_FINGER_DIVISI;
when the command is run appears an error like this:
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.
Here:
'Jam' + CAST(ROW_NUMBER() OVER(..) AS VARHCAR(20))
Unlike other databases (namely, SQL Server), the addition operator in Oracle really means that: addition. So as you are actually trying to add two stings, so Oracle attempts to convert them to numbers - which fails for literal string 'Jam'.
Likely, that you want string concatenation (||) rather than an addition (+):
SELECT
NOABSEN,
TANGGAL,
JAM,
'Jam' || CAST(ROW_NUMBER() OVER (PARTITION BY NOABSEN ORDER BY NOABSEN desc) as VARCHAR(20)) as ColumnsSequence
From HRD_ABS_FINGER_DIVISI;

Updating more than 1 row - Oracle SQL Procedure

I was wondering if it was possible to update more than 1 row with a procedure, im not sure why this one isnt working. Its working only if theres only 1 row in my table. But if there's more than 1 row i get the usual error message :
ORA-01422: exact fetch returns more than requested number of rows
I'm honestly not sure why this isnt working. Is it possible a procedure cannot update more than 1 row at once ?
create or replace procedure TP3_SP_ARCHIVER_ENCAN
is
V_CURRENT_DATE date;
V_DATE_ENCAN date;
begin
select sysdate, DATE_FIN_ENC into V_CURRENT_DATE, V_DATE_ENCAN
from
TP2_ENCAN;
update TP2_ENCAN
set EST_ARCHIVEE_ENC = 1,
STATUT_ENC = 'Archivé'
where V_CURRENT_DATE - V_DATE_ENCAN > 60;
end TP3_SP_ARCHIVER_ENCAN;
/
I'm excepting to archive every ENCAN that has been closed for a duration of 60+ days. everytime i run this procedure i just want to update those.
Full error message :
Error report -
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "C##JALAC144.TP3_SP_ARCHIVER_ENCAN", line 8
ORA-06512: at line 1
01422. 00000 - "exact fetch returns more than requested number of rows"
*Cause: The number specified in exact fetch is less than the rows returned.
*Action: Rewrite the query or change number of rows requested
This line is your problem:
select sysdate, DATE_FIN_ENC into V_CURRENT_DATE, V_DATE_ENCAN from TP2_ENCAN;
You are selecting DATE_FIN_ENC into a scalar variable that can hold exactly one value. You can select "1" into "x". You can't select "1" and "2" into "x" at the same time. So you get the error you're getting.
If I understand your problem correctly, you probably want this, with no initial select:
update TP2_ENCAN
set EST_ARCHIVEE_ENC = 1,
STATUT_ENC = 'Archivé'
where SYSDATE - DATE_FIN_ENC > 60;
Via your code you just want to update record base on current date. Therefore, you do not need to use parameter. Using the update script is enough.
Create or replace procedure TP3_SP_ARCHIVER_ENCAN is:
begin
update TP2_ENCAN
set EST_ARCHIVEE_ENC = 1,
STATUT_ENC = 'Archivé'
where sysdate - DATE_FIN_ENC > 60;
end
TP3_SP_ARCHIVER_ENCAN;

ORA-01438: value larger than specified precision allowed for this column

Following is my code, I dont understand what I'm doing wrong. Any help will be greatly appreciated
CREATE OR REPLACE
PROCEDURE COMP_LATE_FEE(LATE_APT_FINE IN NUMBER, LATE_GRG_FINE IN NUMBER)
AS
DIFF NUMBER;
TYPE MBCUR IS REF CURSOR RETURN MONTHLY_BILL%ROWTYPE;
MONBILL MBCUR;
MBREC MONTHLY_BILL%ROWTYPE;
BEGIN
--DIFF := FLOOR(SYSDATE - (TRUNC(SYSDATE,'MM')));
--DBMS_OUTPUT.PUT_LINE(DIFF);
OPEN MONBILL FOR
-- checking the status of all last month's bills
SELECT * FROM MONTHLY_BILL
WHERE STATUS = 'PENDING' AND SYSDATE > ED_DT;
FETCH MONBILL INTO MBREC;
-- adding the late fee amount for any bills that are past the due date
-- due date = last day of the month
DIFF := FLOOR(ABS(MBREC.ED_DT - (TRUNC(SYSDATE,'MM'))));
UPDATE MONTHLY_BILL
SET LATE_FEE = DIFF * LATE_APT_FINE
WHERE BILL_NUM = MBREC.BILL_NUM;
-- if a garage is rented by the resident then the respective additional fee is included
IF (MBREC.GARAGE_RENT != 0) THEN
UPDATE MONTHLY_BILL
SET LATE_FEE = LATE_FEE + DIFF * LATE_GRG_FINE
WHERE BILL_NUM = MBREC.BILL_NUM;
END IF;
COMMIT;
CLOSE MONBILL;
END;
/
The procedure compiled without any err. But I get the following err when i call the proc
BEGIN
COMP_LATE_FEE(70,20);
END;
/
Error report:
ORA-01438: value larger than specified precision allowed for this column
ORA-06512: at "LALLURI.COMP_LATE_FEE", line 19
ORA-06512: at line 2
01438. 00000 - "value larger than specified precision allowed for this column"
*Cause: When inserting or updating records, a numeric value was entered
that exceeded the precision defined for the column.
*Action: Enter a value that complies with the numeric column's precision,
or use the MODIFY option with the ALTER TABLE command to expand
the precision.
Assuming that the statement at line 19 is this
UPDATE MONTHLY_BILL
SET LATE_FEE = DIFF * LATE_APT_FINE
WHERE BILL_NUM = MBREC.BILL_NUM;
the problem would appear to be that the result of the computation diff * late_apt_fine is too large for the late_fee column in the monthly_bill table. We know that late_apt_fine is 70 based on the value of the parameter that was passed in. Since we don't know the value of the diff variable when there is an error and we don't know the definition of the late_fee column in monthly_bill, it's hard to know whether the problem is that the definition of late_fee needs to be changed or whether the computed value is larger than you expect and the algorithm needs to be changed.

Resources