I am experiencing a very unique cast error I don't understand why it happens with some dates and only in one particular case.
First at all, I cannot change the current code, it's a dynamic query from a legacy application and it's the result of queries to different tables to assemble the query I am having troubles with.
The error is a classic 'conversion failed when converting date and/or time from character string'.
At the beginning I thought it was a classic file naming error, we obtain the date from the file name in the format YYYYMMDD, the file has prefix and suffix and it's always formatted like that. It was pretty common to get wrongly formatted dates but it doesn't happen anymore. The issue is interesting because it only happens in 1 case for some dates that do not look like errors, for example, 20201105 which is basically translated to 11/05/2020 (US Format with month first).
This is the query:
SELECT TOP 1 CAST(LEFT(REPLACE(FileName, 'XXYYY_,''),8) AS DATE) AS MyDate FROM Mytable
The file name in this case is XXYYY_20201105.txt
Why the top 1? Well, it is a very bad design, there are many rows with the same value and it has to take only one to determine the date.
The most interesting part of it, when it fails I can "fix" the error just adding one more column:
SELECT TOP 1 CAST(LEFT(REPLACE(FileName, 'XXYYY_,''),8) AS DATE) AS MyDate, AnotherColumn
FROM Mytable
This query, just adding a column, doesn't fail. That's the weirdest part. I am trying wrap my head around what is the difference between obtaining ONE column and TWO columns. When I add any other column it seems to make the issue disappear.
Thanks a lot.
Related
I am using TO_DATE in one of my PostgreSQL functions and it is throwing errors like date/time field value out of range: "2021901". This is happening for the months of January to September as I need to add zeros in front of them. So I tried to execute a simple select query there as follows as I am using the same syntax in function.
SELECT TO_DATE(2021::varchar||09::varchar||'01','YYYYMMDD')
This is also giving me the error
ERROR: date/time field value out of range: "2021901"
SQL state: 22008
Now if I change the month to October, November, or December it works fine, but for all the other months, it is showing this error. I am actually new to Postgres and not sure how to fix this. It would be very much helpful if someone can point me in the right direction. Thanks
If your input values are numbers (integer), another alternative is to use make_date()
make_date(2021,9,1)
A better and easier way would be to just provide the date correctly and use TO_DATE, so as example do this:
SELECT TO_DATE('2021-09-01', 'YYYY-MM-DD')
If you really want to go your way, you can force a leading zero by using TO_CHAR, like this:
SELECT TO_DATE(2021::varchar||TO_CHAR(09, 'fm00')||'01','YYYYMMDD')
But I recommend to take the first propose.
I am new to Cognos and I am trying to add a filter to a column that only allows rows that are in between Yesterday at 4 AM and today at 3 AM. I have a working query in db2 but when I try to add it to the filter in Cognos I get a parsing error. Also, I found in the properties that the data type for the column I am trying to filter to be Unknown (Unsupported) type. I started off by creating two Data Item Expressions for each time frame I am trying to limit the data by. But I got a parsing error on the first one:
[Presentation Layer].[Cr dtime]=timestamp(current date) - 1 day + 4 hour
This works in my db2 local test database but doesn't even compile in Cognos. I also tried casting the column into a timestamp but that isn't working either. Any help is appreciated. I also tried using the _add_days function but I still get a parsing error. Also sampling the column I get values that appear to be timestamps as this string: 2016-01-02T11:11:45.000000000
Eventually if I get the two filters working I expect the original filter to be close to this syntax:
[Presentation Layer].[Cr dtime] is between [Yesterday 4AM] AND [Today 3AM]
Here is your filter:
[Presentation Layer].[Cr dtime] between
cast(_add_hours(_add_days(current_date,-1),4),timestamp)
and
cast(_add_hours(current_date,3),timestamp)
This works because current_date in Cognos does not have a time component. If you were to cast it directly to a timestamp type you would see the time part of the date as 12:00:00.000 AM, or midnight. Knowing this we can then simply add how much time after midnight we want, cast as a timestamp type and use this in the filter.
I am building a map in CartoDB which uses Postgres. I'm simply trying to display my dates as: 10-16-2014 but, haven't been able to because Postgres includes an unneeded timestamp in every date column.
Should I alter the column to remove the timestamp or, is it simply a matter of a (correct) SELECT query? I can SELECT records from a date range no problem with:
SELECT * FROM mytable
WHERE myTableDate >= '2014-01-01' AND myTableDate < '2014-12-31'
However, my dates appear in my CartoDB maps as: 2014-10-16T00:00:00Z and I'm just trying to get the popups on my maps to read: 10-16-2014.
Any help would be appreciated - Thank you!
You are confusing storage with display.
Store a timestamp or date, depending on whethether you need time or not.
If you want formatted output, ask the database for formatted output with to_char, e.g.
SELECT col1, col2, to_char(col3, 'DD-MM-YY'), ... FROM ...;
See the PostgreSQL manual.
There is no way to set a user-specified date output format. Dates are always output in ISO format. If PostgreSQL let you specify other formats without changing the SQL query text it'd really confuse client drivers and applications that expect the date format the protocol specifies and get something entirely different.
You have two basic options.
1 Change the column from a timestamp to a date column.
2 Cast to date in your SQL query (i.e. mytimestamp::date works).
In general if this is a presentation issue, I don't usually think that is a good reason to muck around with the database structure. That's better handled by client-side processing or casting in an SQL query. On the other hand if the issue is a semantic one, then you may want to revisit your database structure.
I have a decimal date field (TDDATR) that is in the YYYYMMDD format.
I would like to create a field that is TDDATR + 30 days but I am unable to.
Using 'Define Results Field' I have tried a few things;
Simply doing this;
TDDATR + 30 DAYS
But it returned this error: Labeled duration not used correctly.
I tried using the DIGITS and SUBSTR commands to create a field in the DDMMYYYY format and then +30 days but got the same error.
Same as above but in the DD/MM/YYYY format - same error.
Using DATE(TDDATR) but all I see is +'s in the field.
Using DATE( ) on the fields created in step 2 and 3 - still get +'s
I've ran out of ideas - any help would be greatly appreciated.
Query/400 lacks a lot of the features that an SQL based interface has.
I'd urge you to consider switching to Query Manager (STRQM) which is a fully SQL based product. You can even convert Query/400 queries to Query Manager queries with the RTVQMQRY command by having the ALWQRYDFN parm set to *YES.
The other option that IBM is pushing is Web Query. Again, fully SQL based and you can convert Query/400 queries into it.
Having said that, the problem is that FLD + 30 DAYS only works when FLD is a DATE data type. Query/400 includes a DATE() function to convert non-date types into date. But it's very limited in that it only works with character fields formatted according to your job defaults. Assuming you're in the US, it'd only work with a character value of '07/01/15'.
You could do a lot of manipulation in Query/400 and end up with a result field that meets DATE()'s requirements. But a better solution would be to create an SQL view over your table and have your numeric date converted into a date data type in the view.
You can find code examples that show how to convert a numeric YYYYMMDD to a actual date data type in the view. However, I'd recommend create a user defined function (UDF) that will do the conversion for you. That will make it much easier to use in the view and to reuse in other places.
If you'd like, there's an open source package called iDate, that includes all the code required for convert to/from date data types.
Download that, install/compile it and your SQL view becomes
select ... idate(TDDATR,'*CCYMD') as TD_DATE
from myfile
The use of days is as follow
Field Expression
CURDATE_30 days(current(date)) + 30
The solution to your problem is: given the field A dec(8,0)
Field Expression
YYYYMMDD_ date(substr(digits(a),5,2)||'/'||
substr(digits(a),7,2)||'/'||
substr(digits(a),3,2))
NEXT_MONTH DAYS(YYYYMMDD_) + 30
Remember to check the date format in your job description. In the example the format is MDY or MM/DD/YY.
More info here
Based on the information here, I created the below 2 fields;
TDDIGI DIGITS(TDDATR)
TDDAT1 SUBSTR(TDDIGI,7,2)||'/'||
SUBSTR(TDDIGI,5,2)||'/'||
SUBSTR(TDDIGI,3,2)
From here I was able to create a date field;
TDDAT2 DATE(TDDAT1)
Which allowed me to perform the necessary calculations.
The format of TDDAT1 is based on your job description which can be found by;
WRKJOB
Option 2
Page down
Date format..: X
Mine was *DMY, so TDDAT1 was formatted based on this.
I have a weird issue with MS ACCESS 2010.
I have a table RawData with column TaskDate (format is Memo). When I use the below query I am getting the desired data,
`select * from RawData where TaskDate between '01/01/2012' and '12/31/2012'`
But when I use the below query I am not getting any data:
select * from RawData where TaskDate between '01/01/2012' and '01/01/2013'
I don't understand the problem as the data comparison was not happening with this 'Year' value. Please help on this
Oh dude. You realize how bad that is? "No idea how to use a database" style, sadly. Time for reading documentation on data types.
Ok, here we go:
TaskDate (format is Memo)
Yes, and however did that should be publicly flogged. First, this is a TEXT field, second it is for LONG texts which dates never are. Fail on two levels.
If the format is Memo it is text, so "between" compares texts.
'01/01/2012' and '12/31/2012'`
that is left to right.
i.e. first letter 0 or 1, second letter 1 or 2, 4th letter between 0 and 3, 5th letter between 1 and 1. Goes on...
'01/01/2012' and '01/01/2013'
that would mean basically everything of 01/01 on 2012 and 2013 ONLY. Assuming this is a holiday, without tasks - well, no data. Why? because any other date fails. The first characters have to match '01/01/201'.
If you would like do do that properly, you can:
Change the formatting of dates to make sense as text. THat is ISO norm: 2012-01-01 to 2012-12-31. That means they order correct as they go left to right.
Better: Dump the stupid idea to use Memo for dates
Read
http://www.dummies.com/how-to/content/tips-for-choosing-field-types-in-access-2010.html
then use Date/Time as field type, and magically Access will not try to compare texts (which is has no clue what they mean internally, so it can not apply the semantics of dates to them) and compare real dates.
Right now you made sure there is no "date" comparison. It is pure stupid little string, left to right, character by character, no additional logic.