'[pervasive][ODBC Engine Interface]Invalid date, time or timestamp value' When trying to compare dates - pervasive

I cant get past this error.
I have a date field stored in mmddyy format.
I want to only return records with a date after 12/31/2019.
I get that Pervasive uses yyyy-mm-dd by default.
I am reformatting the date with this code:
Convert(Concat('20',Concat(Right(Date,2),Concat('-',Concat(Left(Date,2),Concat('-',Substring(Date)))))),SQL_DATE)
A date value of 081820 returns 44061.
Convert('2019-12-31',SQL_DATE)
returns 43830.
And Convert(Concat('20',Concat(Right(Order_Header.Date_Shipped,2),Concat('-',Concat(Left(Order_Header.Date_Shipped,2),Concat('-',Substring(Order_Header.Date_Shipped,3,2)))))),SQL_DATE) > Convert('2019-12-31',SQL_DATE)
returns
[pervasive][ODBC Engine Interface]Invalid date, time or timestamp value
Ive tried cast and convert... anyone know what I am doing wrong in my And statement (in my where clause) or how I can get around this error?

You might have values that are not valid for a date in your data. You should probably check the records. The Date specification requires a month of 1 to 12, a day of 1 to 31 depending on the month (so Feb 30 would be invalid), and a year of 0000 to 9999. Something like this for months, you'd want to check days as well:
insert into sodate (f1) values ('442020');
insert into sodate (f1) values (' 2020');
select f1, left(f1,2) from sodate where left(f1,2) not in ('01','02','03','04','05','06','07','08','09','10','11','12')
The substring in the first example is missing parameters. Once you've got the date in the right format ('yyyy-mm-dd') you should be able to compare it to a date value without converting it to the SQL_DATE data type. One more thing, you're prepending '20' before all years, what happens if your data has dates from pre-2000? You'll need to account for that. In the PCC, when I run:
select Convert('2019-12-31',SQL_DATE)
I get:
EXPR_1
==========
12/31/2019
I used the folowing:
create table sodate (f1 char(6));
insert into sodate (f1) values ('123119');
insert into sodate (f1) values ('081818');
insert into sodate (f1) values ('081820');
insert into sodate (f1) values ('082020');
select * from sodate;
-- This should give the results you want
select concat(concat(concat(concat(concat('20',right(f1, 2)),'-'),left(f1,2)),'-'),substring(f1,3,2)) from sodate where
concat(concat(concat(concat(concat('20',right(f1, 2)),'-'),left(f1,2)),'-'),substring(f1,3,2)) > '2019-12-31';
-- This query shows you don't need the CONVERT to compare a date.
select concat(concat(concat(concat(concat('20',right(f1, 2)),'-'),left(f1,2)),'-'),substring(f1,3,2)) from sodate where
concat(concat(concat(concat(concat('20',right(f1, 2)),'-'),left(f1,2)),'-'),substring(f1,3,2)) >= now()
And got the following results:
EXPR_1
==============
2019-12-31
2020-08-18
and the second query gives:
EXPR_1
==============
2020-08-20

Related

SQL Server: combine date column and time column, insert into datetime column

I have a database with a date and a time stored separately in datetime columns (not my idea). I need to combine their values to put into another table with a datetime column. As simple as this seems, I just don't seem to be able to do it.
I can get my date value:
cast(sampledate as date) -- returns '2014-11-01'
And my date value:
cast(CollectionTime as time) -- returns '06:46:00.0000000'
I've tried a few different ways of putting them together that look OK.
For example:
concat(cast(sampledate as date) , ' ' , cast(CollectionTime as time)) -- returns '2014-11-05 08:14:00.0000000'
But when I try to insert this into a datetime column, or even just cast it as a datetime value, it doesn't work:
cast(concat(cast(sampledate as date) , ' ' , cast(CollectionTime as time)) as datetime)
-- I get the error 'Conversion failed when converting date and/or time from character string.'
This link warned me against using the FORMAT function, and I've been to some other sites that tell me what NOT to do, but I just can't seem to do this simple thing. Can anyone help? Thanks.
EDIT: Figured it out. This link solved it for older versions of SQL, but not current versions. However, it works fine if you cast to datetime2(0), not datetime.
As I commented above, here is an example where you can add the two datetimes together.
If either column is NOT datetime, simply convert that column to a datetime
Declare #YourTable table (sampledate datetime,CollectionTime datetime)
Insert Into #YourTable values
('2019-06-25 00:00:00','09:09:31')
Select *
,NewDateTime = sampleDate + CollectionTime
From #YourTable
Results
sampledate CollectionTime NewDateTime
2019-06-25 00:00:00.000 1900-01-01 09:09:31.000 2019-06-25 09:09:31.000

insert into not working on oracle in date field

I have created table as:
create table ot.eligible(
id number,
name varchar2(255),
join_date date,
left_date date
);
The problem I am getting is I am unable to insert the data which has date column:
insert into ot.eligible(ID,NAME,JOIN_DATE,LEFT_DATE) values(1,'ashwin',to_date(01/12/2017,'MM/DD/yyyy'),to_date(01/2/2018,'mm/dd/yyyy'));
before i tried without using to_Date and numeric found error was there so,I added to_date but,at this time I got error as:
ORA-01858: a non-numeric character was found where a numeric was expected
My sysdate is:
10/17/2019 8:42:29 PM
when I hitted select sysdate from dual;
You are missing single quotes in dates -
insert into ot.eligible(ID,
NAME,
JOIN_DATE,
LEFT_DATE)
values(1,
'ashwin',
to_date('01/12/2017','MM/DD/yyyy'),
to_date('01/02/2018','mm/dd/yyyy'))

Convert to mm/dd/yyyy and select max value

Using SQL Server 2014, I have a date field named LAST_BASELINE_UPDATE_DATE that is stored as datetime.
I used the CONVERT function to convert to mm/dd/yyyy:
convert(date,LAST_BASELINE_UPDATE_DATE,101) as BASELINE_UPDATE_DATE
What I want to be able to do is then select the MAX value of BASELINE_UPDATE_DATE without creating a table. Is this even possible?
It's a little unclear from your post what your data is and what you're trying to get out. Here are a couple solutions, hopefully one of which is applicable
Assuming you want your result as a string formatted mm/dd/yyyy you can do this
select convert(varchar(10), max(LAST_BASELINE_UPDATE_DATE), 101))
from YourTable
If you just need it as a date, just do
select max(LAST_BASELINE_UPDATE_DATE)
from YourTable
if LAST_BASELINE_UPDATE_DATE is already a string (formatted mm/dd/yyyy) and you want it as a date,
select max(convert(date, LAST_BASELINE_UPDATE_DATE, 101))
from YourTable
I think you are complicating this. Just do the conversion on the max datetime values.
declare #table table (LAST_BASELINE_UPDATE_DATE datetime)
insert into #table
values
('20160701 12:21'),
('20160705 03:21'),
('20160401 19:21'),
('20161201 04:21')
select
convert(varchar(10),max(LAST_BASELINE_UPDATE_DATE),101)
from
#table
This method converts your single returned row, which is the max() value of your datetime columns, as opposed to converting every row and then finding the max value.

SQL update based on query results with two parameters

I've created a virtual table in SQL Server that has 28 days from the current date and each date has rows for time that range from 12-10 pm incremented by 15 min and another value to indicate that it's turned on/off for availability, so it would be something like this:
date time onoff
-------------------------------------------------
2015-04-08 12:00 1
2015-04-08 12:15 1
....continue until 22:00 then start next day
2015-04-09 12:00 1
..... continue for 28 days
I'd like to update the availability based on a query from another table which would return the date, start and end time...
So far I came up with this
update table1
set onoff = 0
where tbl1date in (select tbl2date from table2 where userid = 1)
The problem I'm having is adding in the between certain hours part of the equation and I'm not sure how to do something like this in SQL or how to even search for the answer based on not being able to word it properly...
Can someone help or point me in the right direction?
use a DATETIME, don't use separate DATE and TIME fields.
I think you should take a look at DATEDIFF (https://technet.microsoft.com/pl-pl/library/ms189794(v=sql.110).aspx) function.
Your where query could look like this:
update table1 set onoff = 0
where
DATEDIFF(minute, <MIN_RANGE>, tbl1date) >= 0 and
DATEDIFF(minute, tbl1date, <MAX_RANGE>) >= 0
How you calculate MIN_RANGE and MAX_RANGE depends on your table2 structure.
As suggested, if you have control over the structure, use datetime fields as they are easier to do the comparisons on. I'm going to assume you don't have control over the structure.
In order to compare the datetimes you need to create them from your separate date and times. You can either parse the time field for the hours and minutes and use DATEADD to add the appropriate offsets to the date, or you can use CONVERT to interpret a date time string as a date. Something like
CONVERT(datetime, SUBSTRING(CONVERT(varchar, tbl1date, 121), 1, 10) + ' ' + tbl1time, 121)
What this does is to convert the date to odbc cannonical format and throwaway the time part as it takes only the first 10 characters. Then it appends the time and interprets the whole string as a odbc cannonical datetime string. That format is yyyy-mm-dd hh:mi:ss.mmm. The hours are based on 24 hours. So if your times are in AM/PM format you're going to have to convert them.
If your other table has separate date and times you'd use a similar expression to combine them.
Once you have the datetimes you can do something like this
UPDATE table1
SET onoff = 0
WHERE <expression above> BETWEEN (SELECT min_value FROM table2) AND (SELECT max_value FROM table2)

date format remain same in oracle database

INSERT INTO DELLL (
DATETIMEMY)
SELECT to_date(to_char(SU_MODIFYDATE, 'YYYY/MM/DD'),'YYYY/MM/DD') AS DATETIMEMY
FROM SER_TBLSERVICES WHERE SVE_SERVICEID=422
SU_MODIFYDATE = 01/18/2013
but after insertion in DELLL date (DATETIMEMY) format still same is still same
DATETIMEMY = 01/18/2013
you dont assign a format to a DATE. They are stored internally as a number and have no format. the format comes when you want to select the date. so in your case you should just do this:
first just insert the date as-is, do not try to convert it to a char and back again:
SQL> INSERT INTO DELLL (
2 DATETIMEMY) SELECT SU_MODIFYDATE
3 FROM SER_TBLSERVICES WHERE SVE_SERVICEID=422;
1 row created.
now to select it in a specific format, you can use TO_CHAR to format it.
SQL> select * from delll;
DATETIMEMY
----------
01/18/2013 <-- which isn't what you want to see, you wanted to see yyyy/mmm/dd. so...
SQL> select to_char(DATETIMEMY,'yyyy/mm/dd') DATETIMEMY from DELLL
2 /
DATETIMEMY
----------
2013/01/18
or, to apply to all selects in that session that have a date datatype, you can alter the default display format:
SQL> alter session set nls_date_format='yyyy/mm/dd';
Session altered.
SQL> select * from delll;
DATETIMEMY
----------
2013/01/18
The INSERT or SELECT in your example does not modify how a date is stored. Dates are formatted when you SELECT them, using your current connection format preferences/locale.
You are using TO_DATE, selecting that returned value is the same as with any other date, it will be formatted according to the locale.
DazzaL is right with his answer which discusses formatting, storage and retrieval of dates.
I would like to discuss what you are doing in your code.
Oracle stores dates upto precision of a seconds. In simple terms you can retrieve the date in MM/DD/YYYY HH24:MI:SS format.
By issuing to_date(to_char(SU_MODIFYDATE, 'YYYY/MM/DD'),'YYYY/MM/DD') you are actually truncating the date up to the day part. So when you try to retrieve this value, the HH24:MI:SS part will have 00:00:00 because you have truncated the date.
If you want all the details (from year, month, day to hour, minute and seconds) from SU_MODIFYDATE to be inserted into the column in DELLL, you should just use
INSERT INTO DELLL (
DATETIMEMY)
SELECT SU_MODIFYDATE AS DATETIMEMY
FROM SER_TBLSERVICES WHERE SVE_SERVICEID=422
This will ensure all parts of date in SU_MODIFYDATE column are inserted into the new column.
If you want to truncate the date, for example, upto the minute the use to_date(to_char(SU_MODIFYDATE, 'YYYY/MM/DD HH24:MI'),'YYYY/MM/DD HH24:MI')
Likewise, you can truncate dates from year part upto the second part as per your choice.
If you want to insert truncated dates then you should use the query you already have. If you want to insert dates with all their parts then avoid truncating by using to_char and to_date.

Resources