oracle sql - a non-numeric character was found where a numeric was expected - sql

I know there are loads of postings regarding fixing this error but, I'm just not understanding it!
val_strg1 value is 01.04.2016. I want to use this and not show lines where this date is older than current date, (i.e. and trunc(sysdate) < dv.val_strg1).
But, even though I have used a to_date format, I still get the a non-numeric character was found where a numeric was expected error?
I have tried several to_date formats;
to_date(val_strg1,'DDMMYYYY'), to_date(val_strg1,'DD-MM-YYYY')
The following gives me a 'not a valid month' error?
to_date(val_strg1,'DD-MON-YYYY')
My script...
select val_strg, val_strg1, to_date(val_strg1,'DDMMYYYY')
from sd_domainval_org
where name = 'HYPERCARE_CUNR'
order by sort_no
How can I use the val_strg1 as a date?

It seems you are using a text column (e.g. VARCHAR2) for the date. And you are saying that
to_date(val_strg1, 'DD.MM.YYYY')
results in an error. So you have a value in that column that does not match the pattern. Here is a query to find such invalid entries:
select *
from domainval
where name = 'HYPERCARE_CUNR'
and not regexp_like(val_strg1, '^[[:digit:]]{2}\.[[:digit:]]{2}\.[[:digit:]]{4}$');
You can then correct the wrong entries, but a better solution would of course be not to store dates in string columns at all. Use date columns instead, so as to not have such issues.

if your string date val_strg1 is in the form 'DD.MM.YYYY' (i.e. '01.04.2016'), then you have to use to_date(val_strg1,'DD.MM.YYYY');
for example: Select to_date('01.04.2016','DD.MM.YYYY') from dual;
If you have errors again, probably you have a string in the recordset that is not in a valid form for the to_date function (check the values in the val_strg1 column).
Bye,
Igor

I found an answer...
and trunc(sysdate) < to_date(regexp_substr(val_strg1, '^[[:digit:]]{2}\.[[:digit:]]{2}\.[[:digit:]]{4}$'),'DD.MM.YYYY')
...seems to work OK.

you have to tune formating string to exactly match your date structure
in this case
select val_strg, val_strg1, to_date(val_strg1,'DD.MM.YYYY')
from sd_domainval_org
where name = 'HYPERCARE_CUNR'
order by sort_no;

Related

Change system date suggestions nedded

We have a new software package that allows the company to write SQL code to be place on Query portals. We have several reports we wish to code using the previous day as one of the selections. If a report is ran on MONDAY we want to automatically select the previous FRIDAY as the selection date, We have ORACLE SQL DEVELOPER 4.1. The code we are trying to use is listed below:
SELECT ALERT_CD,ALERT_KEY,CHG_DTM,
CASE
WHEN TO_CHAR(SYSDATE,'fmday')='sunday'
THEN SYSDATE-2
WHEN TO_CHAR(SYSDATE,'fmday')='monday'
THEN SYSDATE-3
ELSE SYSDATE-1
END "change"
FROM SG00400T
WHERE ALERT_CD='AUTO'
and CHG_DTM >= to_date('SYSDATE', 'mm/dd/yyyy')
The error we are receiving:
ORA-01858: a non-numeric character was found where a numeric was expected
01858. 00000 - "a non-numeric character was found where a numeric was expected"
*Cause: The input data to be converted using a date format model was
incorrect. The input data did not contain a number where a number was
required by the format model.
*Action: Fix the input data or the date format model to make sure the
elements match in number and type. Then retry the operation.
The CHG_DTM is a date/time field which could be part of the problem we do not full understand at this time.
Any help would be greatly appreciated.
The expression to_date('SYSDATE', 'mm/dd/yyyy') is are trying to convert the string constant 'SYSDATE' to a date - which can't work.
But you should never, ever call to_date() on a value that is already a date. That will first convert the date value to a varchar just to convert that varchar back to a date which it was to begin with.
So the to_date() function is wrong at that place to begin with. Most probably you want:
and CHG_DTM >= trunc(SYSDATE)

Jasper - Oracle - How to filter by date

I am trying to filter a query by date.
I have this line in my query:
AND (the_date like CONCAT (TO_DATE($P{THE_DATE}, 'YYYY-MM-DD'),'%'))
However, I just cannot seem to compare the parameter date to the database date effectively.
Database date is of type DATE. Parameter is of type String.
I've also tried:
AND (TO_CHAR(the_date) like CONCAT ($P{THE_DATE,'%')
Are my data types wrong? I've tried others but to no avail. Is my query wrong?
I'm using iReport... I looked for some kind of debugging option to see what is actually being executed but didn't find any.
When you want to compare DATEs, you need to convert the literal into DATE using TO_DATE.
No need to use LIKE operator. You could either useTRUNC on the DATE column, however, that would suppress any regular index usage. It would be better to use a DATE RANGE condition.
Remember, DATE has both date and time elements.
For example,
WHERE
the_date >= TO_DATE('14-MAY-2015','DD-MON-YYYY')
AND
the_date < TO_DATE('14-MAY-2015','DD-MON-YYYY') +1;
Instead of literals in above example, you could use your INPUT parameter or the local variable which you have defined as string.
WHERE
the_date >= TO_DATE(in_date,'DD-MON-YYYY')
AND
the_date < TO_DATE(in_date,'DD-MON-YYYY') +1;
The format stored in the databases was like 12/MAY/15.
Although I am convinced I attempted this in the input parameter which was of type String, this proved to be the magic answer :) my input was '12/MAY/15' and it worked.

Oracle: between dates statement gives error 'not valid month'

I'm not sure what I'm doing wrong here. I'm trying to build an oracle query that I will be executing from my php project via oci. I need to select all records between a specific date range.
In trying to get the syntax down, I wrote out this test query:
SELECT * FROM SHIPPED
WHERE user_seq_id = 381 AND
LOT_DATE BETWEEN TO_DATE('05/27/2014', 'MM/DD/YYYY')
AND TO_DATE('06/03/2014','MM/DD/YYYY');
This syntax seems like it should work but it's not. I'm definitely not an oracle developer so I'm positive I"m misunderstanding something. When I've looked at similar posts I haven't found anything that would point to what I'm doing wrong.
This is a rather tricky error. The problem would occur if LOT_DATE were stored as a character string rather than a date -- and the string contained invalid data.
By explicitly converting the right hand side of the comparison to dates, the comparison is attempted by converting the field to a date. And there is an error.
The fix is to fix the data in the field. if something is in a field called "date", then it should probably have a date data type.
For identifying unsupported string value for date - You can create a PL/SQL function which accepts string and validate for correct date format, sample of function:
CREATE OR REPLACE FUNCTION VERIFY_DATE(v_date IN VARCHAR2) RETURN NUMBER IS
v_date1 DATE;
BEGIN
select to_date(v_date) into v_date1 from dual;
RETURN 1;
Exception WHEN Others THEN
RETURN 0;
END;
Now, identify rows which are having invalid string value for which you should correct to run your query:
select * from
(
select VERIFY_DATE(LOT_DATE) DateVerified,s.* from SHIPPED s
)
where
DateVerified=0

How to compare two date values in Oracle based on the date and time

I'm working in an aviation environment where I have to compare two values. The OEM in all its wisdom has stored all datetime values in char. The values to compare are called, say, aibt and sibt
As part of the where clause I need to check if aibt is greater than sibt. So this is what I did :
To_Date(aibt,'YYYYMMDDHH24MISS') > To_Date(sibt,'YYYYMMDDHH24MISS')
When applying to_date, the original char values are converted to : 25.12.2013 12:54:00
But I get the following error :
ORA-01841: (full) year must be between -4713 and +9999, and not be 0
You obviously have some data that can not be converted with TO_DATE to a proper date. Feel free to berate your OEM for not defining constraints or otherwise prevent this from happening.
While he gets around to fix his problems, you can use this as a workaround:
WHERE aibt > sibt
Seems like an error in your data. Try this first:
Select to_date(aibt,'YYYYMMDDHH24MISS') from your_table
Select to_date(sibt,'YYYYMMDDHH24MISS') from your_table
to check if you have some incorrect data in your columns.
When you identified your problematic data in your column, you could find the data that is messing this up with somethin like this:
select *
from yourtable
where not regexp_like(aibdt, '^[[:digit:]]+$')
OR length(aibdt)<4 OR
substr(aibdt,1,4)<0
There was some problem in the data. Also thanks Twinkles for your contribution. I hadnt thought of that. Can anyone explain how comparing two char values work?
I got the answer (what I'd really required) in another post Oracle: how to add minutes to a timestamp? which I used for constructing the comparison :
WHERE To_Date(aibt,'YYYYMMDDHH24MISS')>To_Date(sibt,'YYYYMMDDHH24MISS')+ INTERVAL '15' MINUTE
Thanks everyone!

Oracle to_date() incorrect output

There must be a very simple answer, but I can't find it anywhere.
I have the following which is a section of my select statement:
case when q.renewal_date is not null then
to_date(q._renewal_date, 'DD/MM/YYYY')
else
to_date(w.END_DATE, 'DD/MM/YYYY')
end END_DATE,
according to all of the docs I can find the MM should give the month in numbers however I'm getting results such as:
30-SEP-12
26-JUN-11
30-SEP-12
It's also interesting that they're hyphenated (-) and not with slashes (/).
So what's the reason for this and how do I achieve what I want?
Assuming w.end_Date and q._renewal_date are actual dates, you want to to_char them, not to_date. At present I would say you are seeing the dates in the format specified by your NLS settings. (If they are not dates, you are converting them to dates, but still letting your NLS settings choose the format you view it in)
As you are TO_DATEing the value it is stored by Oracle internally as a date. It is displayed back to you using your NLS_DATE settings value which i would assume are set to DD-MON-YY by default.
You can check with
SELECT *
FROM v$parameter
WHERE name = 'nls_date_format';
You'll need to either alter your NLS_DATE_FORMAT setting (either for your session or for the DB) or TO_CHAR the output to the format you want to see.
to_date converts a string to a date. The code you have is taking a string (q._renewal_date) in 'DD/MM/YYYY' format and converting it to a date. What you are seeing is the default rendering of the date field.
Depending on what type q._renewal_date is, you probably need to use a different conversion/formatting function.