Oracle 11g SQL loader, time format issue - oracle11g

I am trying to load a .csv file using SQL loader. I get this error message on a column that should store time column:
column TIME.ORA-01843: not a valid month
In my .csv file time has the format HH:MM:SS but I can't understand why Oracle does not recognise it.
Using the command select * from nls_session_parameters; I see that the default time format is HH24.MI.SSXFF. I tried to change the time separator in my csv file but I got the same error result.
I have a very simple control file, that looks like below.
LOAD DATA
INFILE Cycling_Accidents0512.csv
INTO TABLE CYCLING_ACCIDENTS
FIELDS TERMINATED BY ','
(ID,
ACC_ID,
OSGB_EASTING,
OSGB_NORTHING,
WGS_LONG,
WGS_LAT,
POLICE_FORCE,
ACC_SEVERITY,
NUM_VEI,
NUM_CAS,
ACC_DATE,
DAY_WEEK,
TIME,
LOC_AUTH_DIS,
LOC_AUTH_HIGH,
FST_ROAD_CLASS,
FST_ROAD_NUMBER,
ROAD_TYPE,
SPEED_LIMIT,
JUNCT_DETAIL,
JUNCT_CONTROL,
SND_ROAD_CLASS,
SND_ROAD_NUM,
PED_HUM,
PED_PHY,
LIGHT_COND,
WEATH_COND,
ROAD_SUR_COND,
SPEC_COND,
CARR_HAZARDS,
URB_RUR,
POLICE_ATT,
LSOA_ACC_LOC,
VEI_TYPE)
If someone of you can help me to modify the control file in order to make the time format acceptable to Oracle, that would be appreciated. I tried to look up on other web resources but I haven't found anything that could help.
Thanks!

You mentioned querying the session NLS parameters, but the value you showed appears to be NLS_TIME_FORMAT, which is only used internally.
Oracle doesn't have a time-only type, so your field is presumably actually a DATE type (or possibly TIMESTAMP). The values in the column will have a date part, even if you ignore it.
SQL*Loader will use NLS_DATE_FORMAT to interpret the data file value for a DATE field. If that is DD/MM/YYYY then it would liberally interpret a value like 22:41:17 as the 22nd day of the 41st month - hence your error - in the year 17.
You can specify the date format model in the control file:
TIME DATE 'HH24:MI:SS',
The value in the table would have that time, on the first day of the current month.
The SQL*Loader documentation does refer to a TIME data type which I have never seen used, and I can't find any references to it anywhere, including MOS. A quick bit of experimentation hasn't helped. If I make the control file entry:
TIME TIME,
... then the record is rejected with ORA-00933: SQL command not properly ended. The log file also shows the data type as DATETIME HH24.MI.SSXFF, which looks related to the NLS_TIME_FORMAT value. I haven't found a way to make it accept that. If I change the column definition from DATE to TIMESTAMP then I get a different error, ORA-00904: "TO_TIME": invalid identifier, which is even stranger. It almost looks like these data types are defined in SQL*Loader for future use. (This discussion suggests they thought about adding TIME as a database type in 10g, but obviously can't verify that. And this is in the SQL*Loader reference at least back to 9i).

Related

Unparseable Date in Grails Domain Class from SQLite Database

I have a sqlite db (it is the spiceworks db) and I am mapping the tables to grails domain classes. There is a table in particular that is in a datetime format (yyyy-MM-dd HH:mm:ss). An example of such a date in the db for anyone who wants to verify would be: 2015-06-26 15:32:39
I created the domain class and mapped my properties to the columns. Let grails generate the views so that they are default. When I try to get to the index page I get:
URI
/spiceworks/weeklyReportItem
Class
java.text.ParseException
Message
Unparseable date: "2015-06-26 15:32:39" does not match (\p{Nd}++)\Q-\E(\p{Nd}++)\Q-\E(\p{Nd}++)\Q \E(\p{Nd}++)\Q:\E(\p{Nd}++)\Q:\E(\p{Nd}++)\Q.\E(\p{Nd}++)
I've used MSSQL datetimes in the past and have never ran into this issue. In the database, the data type for the problematic column is datetime. Anyone know what's going on?
EDIT: I only have Read permissions on the db and the spiceworks source code isn't open source.
If you look at that regular expression, you'll see it's looking for a ISO8601 timestamp formatted like YYYY-MM-DD HH:mm:SS.SSS - in other words, it needs a decimal seconds, and you're just providing whole seconds.
An easy fix would be to update every existing value in the relevant column by appending '.000' to it, and update the insertion routines to do the same.
If you refer to the sqlite date time functions, there's a %f format specifier for strftime() that can be used to produce fractional seconds that might be helpful if you're building the timestamp directly in an insert query.
In the database, the data type for the problematic column is datetime
Sqlite3 doesn't have a datetime type. The timestamps you're storing are strings. More information.

Timestamp in Hive tables keeps changing

I have a HIVE table which stores timestamp in yyyy-MM-dd HH:mm::ss.S format. But I have noticed that The value in such columns keeps changing, e.g. the value that I sqooped was '2016-01-25 00:00:00.0' but sometimes (not always) this value is shown as '2016-01-24 19:00:00.0'.
To make matters worse, this does not happen in all tables at the same time. Sometimes table1 would have the correct format and table2, the incorrect one (2016-01-24 19:00:00.0) and vice versa
I don't know if this is relevant, but we recently moved from ORACLE to HIVE. In the oracle table the date column was of type 'DATE' which stored datda as 25-JAN-16 but in HIVE the column is of type 'TIMESTAMP' and stores data as 2016-01-25 00:00:00.0.
The timestamp is correct when I sqoop the data but is sometimes incorrect when I check it out later.
Could someone please tell me how I could fix or work around this problem?
I believe this is because of the timezone problem. Try using timezone UDFs in hive and check whether you are getting it right.
eg. to_utc_timestamp

Format date from lookup table

My report has a data lookup table with dates in dd/mm/yyyy formart. When I bring it into Crystal it changes the data type to date-time instead of just date.
I tried converting to just a date within Crystal, but when I run a lookup based on parameters (10-1-2016 - 10-31-2016) I get a running cycle of dates. As soon as it hits 10-31-2016 it starts over from 10-1-2016.
I tried setting it to not provider duplicate values to no avail. How I could be doing this better?
If you just need to display the date without the time value, you can format the field when it displays in your report as "System Default Short Format" in the Format Editor. (Date and Time tab)
Otherwise leave the date as-is and create a seperate Formula Date({table.Field}) to use as "just the date". This way you keep the original datetime value as-is, but can use your new Formula when the time value needs to be removed.

Retrieving Data From Returned Oracle Timestamp Column

We have a ColdFusion 8 (Linux) application that uses an Oracle timestamp. We just converted to Oracle 11g from 10g and we're now using Oracle's thin client on the data sources. We're getting an error in the application where a timestamp column is selected.
It seems as though an object of class oracle.sql.TIMESTAMP is being returned. I verified this by dumping the contents of the column. Sure enough, it gives me a break down of the object's methods and their return types. But, I can't seem to be able to interface with this object directly:
<cfquery name="getstuff" ...>
SELECT timestampfld ...
FROM myTable
</cfquery>
getstuff.timestampfld contains an object. But, doing this:
<cfoutput query="getstuff">
#timestampfld.stringValue()#
#timestampfld.dateValue()#
</cfoutput>
produces the error that says those methods can't be found. How can I get at the data held in that object?
Update from comments:
When I take column value and apply the DateFormat( timestampfld, "dd.mm.yyyy" ) function to it. The CF error is
"The value class oracle.sql.timestamp cannot be converted to a date".
When I perform <cfoutput>, I get the class definition.
In the retrieved column, I seem to be getting an object instead of a string. When I cfdump the column, I get OBJECT OF oracle.sql.TIMESTAMP. The dump lays out the methods and fields available. When I cfoutput that same variable, a string is displayed. When I try to perform a DataFormat() on the variable, it complains that its not a date.
I just happened to stumble over this error during my development. I had it in the past and long forgotten since.
I know of two ways to mitigate:
The first is according to an answer of a question regarding the same error message in a different context.
One would add the following to the jvm.config file
-Doracle.jdbc.J2EE13Compliant=true
The second is not to return an Oracle TIMESTAMP column but CAST it do DATE, first, like
<cfquery name="getstuff" ...>
SELECT CAST( timestampfld as DATE ) timestampfld
FROM myTable
</cfquery>
I'm not satisfied with either, to be honest. When the JVM argument is forgotten, the software crashes. The CAST, on the other hand, may influence how the SQL works.

Cast Date in Informix

I have never used Informix before and I'm trying to write a query that will return records over the last 365 days.
Here is the query I have been trying to use:
Select * from Visit where vis_mod_dt between today-365 and today;
That returns no records even though I know that there is data for the last 365 days. I am guessing that the vis_mod_dt in not a true date column, although it displays as '12/31/1899' I have tried to cast this column using:
select * from visit where date(vis_mod_dt) between today-365 and today;
This still returns no data.
Any ideas?
Informix DATE format
Be aware that the date 1899-12-31 corresponds to the internal date representation of zero (0). That is, internally, Informix stores DATE values in a 4-byte integer, and counts the number of days since 1899-12-31, so Day 1 was 1900-01-01 (and since it knows that 1900 was not a leap year, Day 60 was 1900-03-01).
That fact makes me worry about what is in your table. However, if the data in your table cannot be converted to a DATE upon request, normally you would get an error.
What is your table schema?
It would be sensible for you to establish the schema either using DB-Access and the Info/Tables option, or use DB-Schema:
dbschema -d dbase -t visit
The DB-Schema output is more suitable for adding to your question.
The query expressions using 'TODAY-365' and 'TODAY' should work fine - if there is data to select.
DBDATE environment variable
There is an environment variable, DBDATE, that you may need to set to get things to work - to convert from a string representation to dates. Since you are probably based in the UK (from your icon), then you may want and need to set the value of DBDATE to:
export DBDATE=DMY4/
This says that dates consist of the day, the month, a 4-digit year and the '/' is used as the preferred separator. You won't be surprised to learn that the presumed default value is usually 'MDY4/', for US format; I use 'Y4MD-' habitually, so I see DATE value the same as DATETIME YEAR TO DAY, which is the ISO 8601:2004 notation for a date. (It has many benefits: it is unambiguous, and naive sorting algorithms sort such dates into date order.) There's actually a lot of mechanism in the background in IDS (IBM Informix Dynamic Server - which, I assume, is the DBMS that you are using; there are some alternatives that are also Informix DBMS) such that strings with 2-digit dates will usually be converted correctly (but they are ambiguous and undesirable), and separators other than '/' will be recognized on input, but the slash will be used on 'output' (when converting DATE to string).
Information needed to improve the answer to this question - 1st Edition.
If what is here does not help, then I recommend editing your question to include:
The table schema.
A few (2-4) rows of data that you think should be selected but aren't.
Platform and version information. It can help to have the version down to the level of detail of IDS 11.50.FC4W1; occasionally it matters. Most usually, the first three digits are what affect things, of course.
If your table is big (many columns), try to select the key columns (vis_mod_dt is by far the most important one). Ideally, you won't need any scroll bars in the display.
Make sure you don't include any sensitive information.
Information needed to improve the answer to this question - 2nd Edition
I will help you if you pay attention to the questions I ask you. I cannot help you if you do not pay attention to the questions I ask. And please edit your question rather than adding information as an 'answer'.
What is the table schema? What is the output from:
SELECT t.tabid, t.tabname, c.colno, c.colname, c.coltype, c.collength
FROM "informix".systables AS t, "informix".syscolumns AS c
WHERE t.tabid = c.tabid
AND t.tabname = "visit"
ORDER BY t.tabid, c.colno;
What do you get from:
SELECT TODAY, TODAY-365 FROM "informix".systables WHERE tabid = 1;
Do you have the environment variable DBDATE set? If so, what is its value?
Do you have the environment variables CLIENT_LOCALE or DB_LOCALE set? If so, what are their values?
Which version of Informix are you using?
Which platform are you using it on?
Which language or tool are you using to run the query.
Note: if you cannot copy'n'paste the queries above, then you probably do not need to include the quoted '"informix".' attributes on the system catalog; however, as written, the queries will work on any extant Informix database - OnLine 5.x, SE 5.x or 7.x, IDS 7.x, XPS 8.x, IDS 9.x or 10.x or 11.x - and any mode of database (unlogged, logged, MODE ANSI). I'd use the JOIN notation except that some of the older versions don't support it - though you have to be on very old versions for that to be a problem.
This is a little confusing, because when I run the following, I get data:
select count(*) from visit where vis_mod_dt between "10/01/2008" and "10/01/2009"
how about unloading the table to ascii file, examine the unloaded vis_mod_dt values to see if they conform to DBDATE=MDY4 (mmddyyyy) format?.. if they do, ALTER vis_mod_dt to TYPE DATE if it's not a DATE column, then LOAD the unloaded table back in.
the: "BETWEEN today-365 AND today" part of your SELECT statement works for me in my apps.

Resources