Teradata BTEQ - Invalid timestamp issue - teradata

I am trying to execute an sql through TERADATA BTEQ and getting the below error.
But the same sql is running good when getting executed in Teradata SQL assistant.
WHERE S_ORDER_ITEM.LAST_UPD BETWEEN CAST( (('20050614' (DATE, FORMAT 'YYYY-MM-DD')) -1 (CHAR(10)) )|| ' ' || '22:00:01' AS TIMESTAMP(0)) AND CAST( (('20050614' (DATE, FORMAT 'YYYY-MM-DD')) (CHAR(10)) )|| ' ' || '22:00:00' AS TIMESTAMP(0) )
*** Failure 2666 Invalid date supplied for S_ORDER_ITEM.LAST_UPD.

The error message indicates that S_ORDER_ITEM.LAST_UPD is not a date/timestamp (char?) and the automatic typecast to a timestamp fails due to bad data.
This part '20050614' (DATE, FORMAT 'YYYY-MM-DD') should never work, because the string doesn't match the Format.
There's no need for casting a string to a date, because the recommended way to write a date literal is simpler and shorter, using Standard SQL DATE '2005-06-14'.
If the date is actually known you better write
BETWEEN TIMESTAMP '2005-06-13 22:00:01'
AND TIMESTAMP '2005-06-14 22:00:00'
Otherwise don't cast to/from string, use datetime calculations instead:
BETWEEN Cast(DATE '2005-06-14' AS TIMESTAMP(0)) - INTERVAL '01:59:59' HOUR TO SECOND
AND Cast(DATE '2005-06-14' AS TIMESTAMP(0)) + INTERVAL '22:00:00' HOUR TO SECOND
Edit:
If you can't change the input format you need to apply another FORMAT:
BETWEEN Cast((('20050614' (DATE, Format 'YYYYMMDD')) -1 (Format 'yyyy-mm-dd')) || ' ' || '22:00:01' AS TIMESTAMP(0))
AND Cast((('20050614' (DATE, Format 'YYYYMMDD')) (Format 'yyyy-mm-dd')) || ' ' || '22:00:00' AS TIMESTAMP(0))

timestemp error occurs when your phone time is wrong
The solution is to correct your device time

Related

Teradata SQL syntax error : Invalid FORMAT string 'hh:mi:ss.s(7)'

I am trying to get following teradata date format : 2020-04-14 09:10:57.0851800 (GMT-04:00).
Running query like below. It runs fine till 'hh:mi:ss.s(6)'. But gives error if i change it to 7.
Error : Invalid FORMAT string 'hh:mi:ss.s(7)'.
Code:
SELECT
((VLUTN_START_DTM (format 'yyyy-mm-dd')) (varchar(10))) || ' ' || ((VLUTN_START_DTM (format 'hh:mi:ss.s(7)')) (varchar(27))) || ' ' || '(GMT-04:00)' (title ''),
((VLUTN_END_DTM (format 'yyyy-mm-dd')) (varchar(10))) || ' ' || ((VLUTN_END_DTM (format 'hh:mi:ss.s(7)')) (varchar(27))) || ' ' || '(GMT-04:00)' (title '') (title '')
FROM
teradatatable
The column on which you are applying the format is of type Timestamp(6). The precision of the value after seconds is defined using fractional_seconds_precision. Here in this case it is 6. If you try to fetch any value with in the range of 1-6 it will work fine. If you try to fetch the fractional_seconds with a precision of up to 7 places then Teradata starts throwing an error.
You can infer the same from the Teradata documentation.
The data types Time & Timestamp support only 6 fractional digits, thus FORMAT is limited, too.
But TO_CHAR/TO_TIMESTAMP allow up to 9 digits:
to_char(VLUTN_START_DTM, 'yyyy-mm-dd hh:mi.ss.ff7 "(GMT-04:00)"')

Invalid format string in timestamp

I am trying to cast a value to timestamp(0) and insert into a table. The column Port_Out_END_Dttm is timestamp(0). It's giving me invalid format string.
,MAX(coalesce(SRC.Port_Out_END_Dttm,cast('31/12/9999 00:00:00' as timestamp FORMAT 'dd/mm/yyyyBhh:mi:ss(0)') ))as Port_Out_END_Dttm
The entire query is like:
sel
,case when Port_Out_Ver_Phase_END_Dttm in cast ('12/31/9999' as date format 'MM/DD/YYYY') then null else Port_Out_Ver_Phase_END_Dttm end as Port_Out_Ver_Phase_END_Dttm
from
(
sel
,MAX(coalesce(SRC.Port_Out_END_Dttm,cast('31/12/9999 00:00:00' as timestamp FORMAT 'dd/mm/yyyyBhh:mi:ss(0)') ))as Port_Out_END_Dttm
from table
)
First i need to coalesce the nulls to a high end date and then again take that date as null
What's wrong over here?
Thanks for your help.
There's no need to CAST a hard-coded string to a Date/Time/Timestamp, better use a Standard SQL Date/Time/Timestamp Literal instead:
TIMESTAMP '9999-12-31 00:00:00'
DATE '9999-12-31'
TIME '00:00:00'
MAX(COALESCE(SRC.Port_Out_END_Dttm, TIMESTAMP '9999-12-31 00:00:00'))
Btw, you might need to add a time zone to the literal, otherwise it might be based on your session time zone:
TIMESTAMP '9999-12-31 00:00:00+00:00'
Your syntax looks slightly off to me. Try this version:
MAX(COALESCE(SRC.Port_Out_END_Dttm,
CAST('31/12/9999 00:00:00' AS timestamp(0) FORMAT 'DD/MM/YYYYbhh:mi:ss')))

Lazarus SQLite date entry displays improperly

UPDATE: Issue was solved by #whosrdaddy. See comments below this question.
I am trying to resolve the following peculiar case: In a friend's Lazarus project, he tries to query an entry in SQLite. The asString()-method (in the procedure for displaying appointments) returns the proper date on Windows 64 Bit. On a 32 Bit operating system, however, only the first two digits are displayed ('16' instead of '28.02.2016'). What could be the reason?
This is the source code for initialising the form:
// Initialise Form
procedure TForm1.FormCreate(Sender: TObject);
begin
SQLite3Connection1.DatabaseName:='Kalender.sqlite';
SQLTransaction1.Database:=SQLite3Connection1;
SQLQuery1.Transaction:=SQLTransaction1;
// Create Table "tblTermine"
SQLQuery1.SQL.text := 'CREATE TABLE IF NOT EXISTS tblKalender (Datum DATETIME, Termin VARCHAR(10))';
SQLQuery1.ExecSQL;
SQLTransaction1.commit;
end;
There are two further procedures:
// Display Appointments
procedure TForm1.Button1Click(Sender: TObject);
begin
ListBox1.Clear;
SQLQuery1.Close;
SQLQuery1.SQL.text:='SELECT * FROM tblKalender';
SQLQuery1.Open;
while not SQLQuery1.Eof do
begin
// Should return 'dd.mm.yyyy'
ListBox1.Items.add(SQLQuery1.Fields[0].AsString+ ': ' + SQLQuery1.Fields[1].AsString);
SQLQuery1.Next;
end;
end;
// Save Appointment
procedure TForm1.Button2Click(Sender: TObject);
var Termin: string;
Datum: TDate;
begin
Termin:=Edit1.text;
if calendardialog1.execute then
Datum:=TDate(calendardialog1.date);
SQLQUERY1.close;
SqlQuery1.SQL.text:= 'Insert into tblKalender Values (:Datum, :Termin)';
SqlQuery1.ParamByName('Datum').AsDate:= Datum;
SqlQuery1.ParamByName('Termin').AsString:= Termin;
SqlQuery1.ExecSQL;
SqlTransaction1.Commit;
Button1.Click;
Edit1.Text := '';
end;
The intended output into the TListBox would be something like this.
you should convert first the DateTime to a Julian Date
function DateTimeToJulianDate(const Datum: TDateTime): Double;
and
SqlQuery1.SQL.text:= 'Insert into tblKalender Values (:Datum, :Termin)';
SqlQuery1.ParamByName('Datum').AsFloat := DateTimeToJulianDate(Datum);
...
SqlQuery1.ExecSQL;
to test and get the value use :
function TryJulianDateToDateTime(const AValue: Double; ADateTime: TDateTime):Boolean;
if TryJulianDateToDateTime(SQLQuery1.Fields[0].AsFloat,myDate)
then
ListBox1.Items.add(DateTimeToStr(myDate)+ ': ' + .....
else
ShowMessage('Not a valid Julian date');
Update
SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic
Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Double Test
procedure TForm1.Button3Click(Sender: TObject);
var
Datum : TDate;
myDate : TDateTime;
JulianDouble : Double;
begin
// uses ....,DateUtils
Datum := StrToDate('01.01.2013'); //German Culture settings
Memo1.Lines.Add('01/01/2013 = '+DateTimeToStr(Datum)+ ' TDate as Text');
Memo1.Lines.Add('01/01/2013 = '+FloatToStr(Datum) + ' TDate Double');
JulianDouble := DateTimeToJulianDate(Datum);
Memo1.Lines.Add('01/01/2013 = '+FloatToStr(JulianDouble) + ' Julian Double');
if TryJulianDateToDateTime(JulianDouble,myDate)
then
Memo1.Lines.Add('01/01/2013 = '+DateTimeToStr(myDate)+ ' TDate as Text')
else
ShowMessage('Not a valid Julian date');
end;
Output :
01/01/2013 = 01.01.2013 TDate as Text
01/01/2013 = 41275 TDate Double
01/01/2013 = 2456293,5 Julian Double
01/01/2013 = 01.01.2013 TDate as Text
Update-2 :
To write Delphi TDate Double to a SQLite Date field is wrong
Your comment shows me that you do not know the problems.
Of course you can directly write a Delphi Double value into a database field. And read it back to a TDateTime.
This will quickly lead to problems.
Examples:
SQLite:
These functions only work for dates between 0000-01-01 00:00:00 and
9999-12-31 23:59:59 (julidan day numbers 1721059.5 through 5373484.5).
For dates outside that range, the results of these functions are
undefined.
41275 Delphi TDate Double for 2013/01/01 is outside of above range !!
SQLite's own date functions can no longer be used.
Compute the current date.
SELECT date('now');
Compute the last day of the current month.
SELECT date('now','start of month','+1 month','-1 day');
Compute the date and time given a unix timestamp 1092941466.
SELECT datetime(1092941466, 'unixepoch');
Compute the date and time given a unix timestamp 1092941466, and compensate for your local timezone
SELECT datetime(1092941466, 'unixepoch', 'localtime');
Compute the number of days since the signing of the US Declaration of Independence.
SELECT julianday('now') - julianday('1776-07-04');
etc. etc.
Changing the date value with above functions will give you a double 2456293,5 for a Date 2013/01/01
If you now use unproved and pass it to a Delphi TDateTime it will be 3387/11/26).
This is not far from the maximum value of a TDateTimePicker.
which is 2958465.5 and means 9999/12/31
DateTimePicker1.DateTime := 2958465.5;
DateTimePicker1 9999/12/31
If one already know that it is wrong one should not use it up to a crash.
SQLite uses something called manifest typing which means that if you store values of (Delphi) type TDateTime, SQLite will store the underlying floating point value without warning or message, and offer you the value back so you won't notice that SQLite doesn't treat this as a date-time-value, unless you're trying to manipulate the value from SQL.
To counteract this, I use this bit of SQL code to convert Delphi TDateTime values to an actual SQL datetime:
datetime('1900-01-01','+'||(myDateField-2)||' day')
(see also here)

How to keep the military format when converting string to timestap in Oracle?

This is my code:
l_ts := to_timestamp((d || ' 13:00:00'), 'DD.MM.YYYY:HH24:MI:SS');
u_ts := to_timestamp((d || ' 17:00:00'), 'DD.MM.YYYY:HH24:MI:SS');
I keep getting:
26-MAY-13 01.00.00.000000 PM 26-MAY-13 05.00.00.000000 PM
I want:
26-MAY-13 13.00.00.000000 PM 26-MAY-13 17.00.00.000000 PM
i.e. 13 and 17 instead of 1 and 5.
Thanks for hrlping
You are converting string to date, and then display the date directly.
When You do it that way, the output is formatted to string internally and it depends on You session locale settings.
If You want to get the date in exactly the format You want, You should use TO_CHAR function that will format Your date back to string when You need it to be displayed to User. With TO_CHAR You can use format models to get Your date in any format You wish (try to do it in SQL server... ;).
Consider this script:
set serveroutput on;
DECLARE
l_ts TIMESTAMP;
BEGIN
-- Here You get DATE from STRING
l_ts := to_timestamp(('01.01.2013' || ' 13:00:00'), 'DD.MM.YYYY:HH24:MI:SS');
-- Here You get STRING representation of Your DATE.
-- Representation depends on You session settings,
-- and should not be relayed upon.
dbms_output.put_line(l_ts);
-- Examples how You can display DATE as STRING in any way You need
dbms_output.put_line(TO_CHAR(l_ts,'YYYY-MM-DD HH24:MI:SS'));
dbms_output.put_line(TO_CHAR(l_ts,'YYYY-MM-DD HH12:MI:SS AM'));
END;
Hope that will clear the issue. :)

I want to combine date and time and compare with utc date

When I write this query
SELECT Convert(datetime,Convert(varchar,CAST(GETUTCDATE() AS DATE))+' '+
CONVERT(varchar, cast(meas_pain.datetime AS time))) FROM meas_pain
it works for me but when I use the same part in WHERE clause it gives error 'Conversion failed when converting date and/or time from character string.'
SELECT schedules.id
FROM meas_pain LEFT JOIN schedules ON schedules.id=meas_pain.schd_id
WHERE meas_pain.schd_id=9150 AND
Convert(datetime,(Convert(varchar,CAST(GETUTCDATE() AS DATE))+' '+
CONVERT(varchar, cast(meas_pain.datetime AS time)))) <
CONVERT(datetime,DATEADD(Minute,0,getutcdate()))
can anybody explain??
I am not sure why this error does not appear in your select statement, since I can reproduce the error using just
SET DATEFORMAT DMY;
SELECT CONVERT(DATETIME, CONVERT(VARCHAR,CAST(GETUTCDATE() AS DATE)))
Example of Error
You are relying on localised conversion settings, you should use explicit conversion, e.g.
SET DATEFORMAT DMY;
SELECT CONVERT(DATETIME, CONVERT(VARCHAR, CAST(GETUTCDATE() AS DATE), 111), 111)
By explicitly defining the date format to convert both to varchar and from varchar (111) you can avoid any implied conversions.
However, If your dates/times are stored as such there should be no need for all the conversion to and from varchar, this is just more chance for things to go wrong, and unnecessary work, you can simply add a time to a datetime. e.g.
DECLARE #Date1 DATETIME = DATEADD(HOUR, 1, GETUTCDATE()),
#Date2 DATETIME = DATEADD(DAY, 1, GETUTCDATE());
SELECT [Date1] = #Date1,
[Date2] = #Date2,
[Date1/Time2] = CAST(CAST(#Date1 AS DATE) AS DATETIME) +
CAST(#Date2 AS TIME);
From what I can gather from your query you are just trying to get results where the time of meas_pain.datetime is less that the current UTC time, regardless of date. So you should be able to simplify your query to just:
SELECT schedules.id
FROM meas_pain
LEFT JOIN schedules
ON schedules.id = meas_pain.schd_id
WHERE meas_pain.schd_id = 9150
AND CAST(meas_pain.[DateTime] AS TIME) < CAST(GETUTCDATE() AS TIME);
And remove further redundant conversions.
Simplified example on SQL Fiddle
ADENDUM
Apparently this time comparison is not what you are after (although it is what the query you have posted is doing), so I am assuming GETUTCDATE() is just for demonstration.
The conversion you are trying to perform is equivalent to this:
CAST(CAST(GETUTCDATE() AS DATE) AS DATETIME) + CAST(meas_pain.[DateTime] AS TIME)
Another example on SQL Fiddle using the above conversion

Resources