Have a positional flat file schema with date as data type. We have format as ddMMyy. We have a requirement where 000000 needs to be allowed in date field.
When 000000 is passed in the flat file, we are getting Date is not in valid Gregorian date format.
To resolve this I have tried padding with padding character 0 and min occurs as 0. This make 000000 as valid value but it is not taking real valid date values.
Apart from regex expression, is there any way I can have this resolved?
If the field might contain "000000" then you can't use a date/datetime type on it.
Instead, treat it as a String for the Flat File.
You should the conversion from/to the 6 char value in a Map. The Flat File properties don't give you enough options.
If you can change the data type, you could create a new type with xsd:union that accepts any Date and String with the restriction "000000".
xsd:union
Related
I am trying to import a .csv file to match the records in the database. However, the database records has leading zeros. This is a character field The amount of data is a bit higher side.
Here the length of the field in database is x(15).
The problem I am facing is that the .csv file contains data like example AB123456789 wherein the database field has "00000AB123456789" .
I am importing the .csv to a character variable.
Could someone please let me know what should I do to get the prefix zeros using progress query?
Thank you.
You need to FILL() the input string with "0" in order to pad it to a specific length. You can do that with code similar to this:
define variable inputText as character no-undo format "x(15)".
define variable n as integer no-undo.
input from "input.csv".
repeat:
import inputText.
n = 15 - length( inputText ).
if n > 0 then
inputText = fill( "0", n ) + inputText.
display inputText.
end.
input close.
Substitute your actual field name for inputText and use whatever mechanism you are actually using for importing the CSV data.
FYI - the "length of the field in the database" is NOT "x(15)". That is a display formatting string. The data dictionary has a default format string that was created when the schema was defined but it has absolutely no impact on what is actually stored in the database. ALL Progress data is stored as variable length length. It is not padded to fit the display format and, in fact, it can be "overstuffed" and it is very, very common for applications to do so. This is a source of great frustration to SQL reporting tools that think the display format is some sort of length limit. It is not.
I use below code and its working fine. I don't want to change temp table field(dActiveDate) type but please help me to change the date format.
Note - Date format can be changed by user. It can be YY/MM/DD or DD/MM/YYYY or MM/DD/YY and so on...
DEFINE TEMP-TABLE tt_data NO-UNDO
FIELD cName AS CHARACTER
FIELD dActiveDate AS DATE.
CREATE tt_data.
ASSIGN
tt_data.cName = "David"
dActiveDate = TODAY
.
OUTPUT TO value("C:\Users\ast\Documents\QRF\data.csv").
PUT UNFORMATTED "Name,Activedate" SKIP.
FOR EACH tt_data NO-LOCK:
EXPORT DELIMITER "," tt_data. /* There are more than 15 fields available so using export delimeter helps to have less lines of code*/
END.
OUTPUT CLOSE.
As this a "part two" of this question: How to change date format based on variable initial value? why not build on the answer there?
Wrap the dateformat part in a function/procedure/method and call it in the EXPORT statement. The only change required will be to specify each field rather than just the temp-table.
EXPORT DELIMITER ","
dateformat(tt_data.dactivedate, cDateFormat)
tt_data.cName
This assumes that there's a function called dateformat that takes the date and format and returns a string with the formatted date (as in the previous question).
"and so on..." needs to be specified. Depending on the specification you may have to resort to a custom function like Jensd's answer.
If you can constrain the formats allowed, you can use normal handling by using:
session:date-format = "ymd" / "mdy" / "dmy".
session:year-offset = 1 / 1950. // for four vs two digit year
How you populate these two variables can be done in similar fashion as in the other question.
You may need to reset these session attributes to their initial state in a finally block.
DEFINE VARIABLE cDateTime AS CHARACTER NO-UNDO.
DEFINE TEMP-TABLE tt_data NO-UNDO
FIELD DateTime AS DECIMAL FORMAT "->>,>>9.99".
ASSIGN
cDateTime = "20191604121566".
CREATE tt_data.
ASSIGN
tt_data.DateTime = DECIMAL(cDateTime) /* Message Date and Time */
But it says:
"Value cannot be displayed using ->>>,>>>,>>9.999999".
Could you please help this case and tell me what is wrong here?
The code that you show does not result in the error that you are reporting.
I'm guessing that you have a DISPLAY statement somewhere in your real code.
The reported error simply means that that DISPLAY format is not wide enough for the data. By default DISPLAY will use whatever format you specified in the definition of a data element. If you did not specify anything then every datatype also has a default. For decimals the default is "->>,>>>.99".
You can either increase the format in the definition or override it in the display statement like so:
display tt_data.DateTime format ">>>>>>>>>>>>>>>9".
Note: the display format has no influence on the values that you can store in a field. You can always "overstuff" more data into a variable than you can display. The format is only for output display purposes -- it has nothing to do with storage.
The assignment works fine, however the display not.
So ...
DISPLAY tt_data.DateTime.
... does not work because it uses format "->>,>>9.99".
You can change the format in the definition, for example "99999999999999", or do:
DISPLAY tt_data.DateTime FORMAT "99999999999999".
I insert my date/time data into a CHAR column in the format: '6/4/2015 2:08:00 PM'.
I want that this should get automatically converted to format:
'2015-06-04 14:08:00' so that it can be used in a query because the format of DATETIME is YYYY-MM-DD hh:mm:ss.fffff.
How to convert it?
Given that you've stored the data in a string format (CHAR or VARCHAR), you have to decide how to make it work as a DATETIME YEAR TO SECOND value. For computational efficiency, and for storage efficiency, it would be better to store the value as a DATETIME YEAR TO SECOND value, converting it on input and (if necessary) reconverting on output. However, if you will frequently display the value without doing computations (including comparisons or sorting) it, then maybe a rococo locale-dependent string notation is OK.
The key function for converting the string to a DATETIME value is TO_DATE. You also need to look at the TO_CHAR function because that documents the format codes that you need to use, and because you'll use that to convert a DATETIME value to your original format.
Assuming the column name is time_string, then you need to use:
TO_DATE(time_string, '%m/%d/%Y %I:%M %x') -- What goes in place of x?
to convert to a DATETIME YEAR TO SECOND — or maybe DATETIME YEAR TO MINUTE — value (which will be further manipulated as if by EXTEND as necessary).
I would personally almost certainly convert the database column to DATETIME YEAR TO SECOND and, when necessary, convert to the string format on output with TO_CHAR. The column name would now be time_value (for sake of concreteness):
TO_CHAR(time_value, '%m/%d/%Y %I:%M %x') -- What goes in place of x?
The manual pages referenced do not immediately lead to a complete specification of the format strings. I think a relevant reference is GL_DATETIME environment variable, but finding that requires more knowledge of the arcana of the Informix product set than is desirable (it is not the first thing that should spring to anyone's mind — not even mine!). If that's correct (it probably is), then one of %p and %r should be used in place of %x in my examples. I have to get Informix (re)configured on my machine to be able to test it.
I am using SQLite for a project and < symbol is not working in the query.
There is a table named Holidays which has a field of datatype datetime.
Suppose the table contains some dates of current year in the column HolidayDate.
SELECT HolidayDate
FROM Holidays
WHERE (HolidayDate >= '1/1/2011')
AND (HolidayDate <= '1/1/2012')
The < symbol in the above query is not working. > symbol in the above query is working well.
Please help me.
Try:
SELECT HolidayDate
FROM Holidays
WHERE HolidayDate >= date('2011-01-01')
AND HolidayDate <= date('2012-01-01')
(date format must be YYYY-MM-DD)
There is no datetime datatype in sqlite.
Sqlite only has 4 types:
integeral number
floating-point number
string (stored either as utf-8 or utf-16 and automatically converted)
blob
Moreover, sqlite is manifest-typed, which means any column can hold value of any type. The declared type is used for two things only:
inserted values are converted to the specified type if they seem to be convertible (and it does not seem to apply to values bound with sqlite_bind_* methods at all)
it hints the indexer or optimizer somehow (I just know it has trouble using indices when the column is not typed)
Even worse, sqlite will silently accept anything as type. It will interpret it as integeral type if it starts with "int", as string if it contains "char" or "text", as floating-point number if it is "real", "double" or "number" and as blob if it's "blob". In other cases the column is simply untyped, which poses no problem to sqlite given how little the typing means.
That means '1/1/2011' is simply a string and neither dates in format 'mm/dd/yyyy' nor dates in format 'dd/mm/yyyy' sort by date when sorted asciibetically (unicodebetically really).
If you stored the dates in ISO format ('yyyy-mm-dd'), the asciibetical sort would be compatible with date sort and you would have no problem.