I am trying to create a control file for SQL*Loader script. I have a date column that is defined as NOT NULL. I need to set-up the script to use current date, if the incoming value from the file is blank. I tried a few ways - some examples below - but I keep getting below error when running sql loader, but the format works if I do select from dual
How do I need to set it up in SQLLoader?
PROGRAM_CHANGE_TS POSITION(37:47) DATE "decode(length(trim(:PROGRAM_CHANGE_TS)), 11, to_date(:PROGRAM_CHANGE_TS,'yymmddHH24:MI'),to_date(sysdate,'yymmddHH24:MI'))",
PROGRAM_CHANGE_TS POSITION(37:47) DATE "NVL(Decode(:PROGRAM_CHANGE_TS,'00/00/0000',TO_DATE('01/01/2010','dd/mm/yyyy'),TO_DATE(:PROGRAM_CHANGE_TS,'dd/mm/yyyy')),TO_DATE('01/01/2010','dd/mm/yyyy'))",
oracle decode example ORA-00907: missing right parenthesis
select decode(length(trim(:PROGRAM_CHANGE_TS)), 11, to_date(:PROGRAM_CHANGE_TS,'yymmddHH24:MI'),to_date(sysdate,'yymmddHH24:MI')) from dual
or
select NVL(Decode(:PROGRAM_CHANGE_TS,'00/00/0000',TO_DATE('01/01/2010','dd/mm/yyyy'),TO_DATE(:PROGRAM_CHANGE_TS,'dd/mm/yyyy')),TO_DATE('01/01/2010','dd/mm/yyyy')) from dual
works
What changes do I need to make to use it from a sql loader control file?
You're using to_date in the ctl-file, so remove the explicit DATE specifier.
Also, you don't need to use use decode and length, nvl along with trim is the way to go.
Finally, sysdate is already a date, so you don't need to explicitely convert it into a date with to_date.
The following should work (not tested):
PROGRAM_CHANGE_TS POSITION(37:47) "nvl(to_date(trim(:PROGRAM_CHANGE_TS),'yymmddHH24:MI'),sysdate)",
I need to set-up the script to use current date, if the incoming value from the file is blank.
If you get NULL value for the date column, then simply use NVL function to load SYSDATE instead.
PROGRAM_CHANGE_TS POSITION(37:47) DATE "NVL(:PROGRAM_CHANGE_TS, SYSDATE)"
Don't be confused between BLANK and NULL. 00/00/0000 is neither blank nor null. If you are getting 00/00/0000 as the value, then use DECODE.
PROGRAM_CHANGE_TS POSITION(37:47) DATE "DECODE(:PROGRAM_CHANGE_TS, '00/00/0000', SYSDATE, :PROGRAM_CHANGE_TS)"
Related
How to use to_date function in oracle-sqldeveloper to convert a string
May 1 2019 12:00 to date datatype? Does Date in SQL store time too,
or it only stores date? I tried using the to_date function with some
format but it always removes the time part.
If the time is not possible in Date datatype what could be a good alternative?
You can convert your date to a string with (assuming 24-hour values, which seems likely as you don't have an AM/PM marker):
to_date('May 1 2019 12:00', 'Mon DD YYYY HH24:MI', 'nls_date_language=English')
The format elements are in the documentation. I've included the optional third argument to to_date() because your month name has to be interpreted in English, regardless of your session settings.
it always removes the time part
Oracle dates always have both date and time parts, even if the time is set to midnight. You're probably seeing the result of that query as '01-MAY-19'.
Dates don't have any intrinsic human-readable format; Oracle uses its own internal representation, which you generally don't need to worry about.
In most clients and IDEs the session NLS_DATE_FORMAT setting is used to display native dates as strings. For historic reasons that still defaults to DD-MON-YY, despite Y2K, during database creation. it can be changed at database level, and sessions will then inherit that. But each session can override it, e.g. by issuing:
alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'
You can also explicitly convert a date value back to a string, and specify which format elements you want to include, via a to_char() call. Only do that when displaying a value - if you're storing dates or passing them around to functions, always do that as the proper date data type, not as strings. (If you have to pass them outside the database as strings, e.g. to a remote API, you'd usually want to use an ISO-8601 format).
db<>fiddle showing the default output, explicitly formatted as a string (again, for display only - do not store or manipulate dates as string), and with the session format modified.
In SQL Developer you can also go to Tools->Preferences->Database->NLS and change the 'Date format' there - that setting will then apply when you create new sessions, without having to issue alter session each time.
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 have a date time column which is of the following format:
2019-11-10-07.10.55.865000
I want my format to be as follows:
2019-11-10 07:10:55.865000
How can I do this in PostgreSQL 9.6.11?
We can try making a full roundtrip from text to timestamp, then back to text again:
SELECT
TO_CHAR(TO_TIMESTAMP('2019-11-10-07.10.55.865000', 'YYYY-MM-DD-HH.MI.SS.US'),
'YYYY-MM-DD HH:MI:SS.US') AS ts_out;
This outputs:
2019-11-10 07:10:00.865000
Demo
As a side note, you should seriously consider not storing your timestamps as text in the first place. Ideally, if you want to view your timestamp column a certain way, e.g. for reporting purposes, you should only have to make a single call to TO_CHAR with the format mask you want to use.
There is the to_char(timestamp, text) function, e.g. to_char(current_timestamp, 'HH12:MI:SS')
https://www.postgresql.org/docs/current/functions-formatting.html
Select CONVERT(Date, '13-5-2012')
When i run the above T-SQL statement in Management Studio, i get i get the following error:
"Conversion failed when converting date and/or time from character string"
Is there away i can cast that value to a valid Date type successfully? I have such values in a nvarchar(255) column whose dataType i want to change to Date type in an SQL Server table but i have hit that error and i would like to first do a conversion in an Update statement on the table.
Specify what date format you are using:
Select CONVERT(Date, '13-5-2012', 105)
105 means Italian date format with century (dd-mm-yyyy).
Ref: http://msdn.microsoft.com/en-us/library/ms187928.aspx
In general, I'd suspect usually there is data which can't be converted in a column, and would use a case statement checking it's convertable first:
SELECT CASE WHEN ISDATE(mycolumn)=1 THEN CONVERT(Date, mycolumn, [style]) END
FROM mytable
I believe Convert relies on the SQL Server date format setting. Please check your dateformat setting with DBCC USEROPTIONS.
I suspect if you set the dateformat to dmy it'll understand:
SET DATEFORMAT dmy
GO
If even then it doesn't work, you can't find a style that matches your data, and if your data is in a consistant format, it's down to manual string manipulation to build it (don't do this if you can help it).
Try this....
Select CONVERT(Date,'5-13-2012')
Use 'mm-dd-yyyy' format.
CONVERT assumes that the original data can represent a date. One bad data item can throw the same conversion error mentioned here without pointing to the problem.
Using ISDATE helped me get around the bad data items.
SELECT CONVERT(DATE, CONVERT(CHAR(8), FieldName))
FROM DBName
WHERE ISDATE(FieldName) <> 0
You need to give the date format while conversion, this will resolve the error.
select convert(date, '13-5-2012' ,103)
I'm getting the following error message
ERROR: date/time field value out of range: "13/01/2010"
HINT: Perhaps you need a different "datestyle" setting.
I want to get my date in the format DD/MM/YYYY
SHOW datestyle;
DateStyle
-----------
ISO, MDY
(1 row)
INSERT INTO container VALUES ('13/01/2010');
ERROR: date/time field value out of range: "13/01/2010"
HINT: Perhaps you need a different "datestyle" setting.
SET datestyle = "ISO, DMY";
SET
INSERT INTO container VALUES ('13/01/2010');
INSERT 0 1
SET datestyle = default;
SET
http://www.postgresql.org/docs/current/static/runtime-config-client.html#GUC-DATESTYLE
DateStyle - Sets the display format
for date and time values, as well as
the rules for interpreting ambiguous
date input values.
For historical reasons, this variable
contains two independent components:
the output format specification (ISO,
Postgres, SQL, or German) and the
input/output specification for
year/month/day ordering (DMY, MDY, or
YMD).
Of course it's best to use unambiguous input format (ISO 8601), but there is no problem to adjust it as you need.
You could set the date style to European dd/mm/yyyy:
SET DateStyle TO European;
I'd advise against this though. I generally try to convert between formats, and keep ISO formatted dates in the data source. After all, it's only a matter of representation, not a matter of different data.
Edit:
When using this COPY, the valid input format is defined by the server configuration and can either be changed for the current session using the SET command as described by Berry or by adjusting the server configuration.
DateStyle description in the manual:
http://www.postgresql.org/docs/current/static/runtime-config-client.html#GUC-DATESTYLE
The following is not valid for the real situation, but I'm keeping it for reference anyway
When using date (or timestamp) literals always specify a format mask to convert them. Otherwise your statements aren't portable and won't necessarily run on every installation.
The ANSI SQL standard for date literals is like this:
UPDATE some_table
SET date_column = DATE '2011-05-25'
WHERE pk_column = 42;
If you cannot change the literal format, you need to apply the to_date() function
UPDATE some_table
SET date_column = to_date('13/01/2010', 'dd/mm/yyyy')
WHERE pk_column = 42;
If this is not what you are doing you should show us the full SQL statement that generated the error.