Oracle timestamp column dropping fractions of seconds - oracle

We are testing one of our test Oracle databases upgraded from 12.1 to 12.2 and have come across a fairly serious problem.
Some of our tables include columns of type timestamp with time zone. At the time of the upgrade these contain values that can and do include fractions of seconds.
What we have noticed is that any routine that now (under 12.2) tries to populate data in such columns results in the fractional seconds value being truncated and the value being rounded to the nearest second. It is almost as if we are attempting to insert a timestamp into a date field.
E.g. if we try and insert the value '01-JAN-2017 12:34:56.789' into a TTZ column in the 12.2 instance, the value that gets inserted is actually '01-JAN-2017 12:34:57.000'.
What's worse is that this data loss is occurring silently, with no warning given.
Anyone else had this?

Related

Oracle TRUNC function doesn't work in perl

I try to insert the created field in my_table. The created field has a datetime type. In my_table the field my_created has a date format. So I try to TRUNC the created field. However I'm getting the error ORA-01830: date format picture ends before converting entire input stringwhile inserting the truncated value. It seems, that the time is still there but is reset to 00:00. how can I get only the date without time? It happens only in perl. I'm getting only date in toad.
Very simplified code looks like:
my $SQL="SELECT
TRUNC(CREATED),
FROM
DBA_OBJECTS";
my $sth = $db->prepare($SQL);
$sth->execute();
my $date = $sth->fetchrow();
$SQL = "INSERT INTO MY_TABLE
(MY_CREATED)
VALUES (?)";
my $stmt = $dbh_master->prepare($SQL);
$stmt->execute($date);
EDIT:
I found an ugly workaround and I'm executing it like this:
$stmt->execute(substr($date, 0, 10));
However maybe someone has a nicer solution.
How can I get only the date without time?
In Oracle, a DATE is a binary data type that is composed of 7 bytes representing: century, year-of-century, month, day, hour, minute and second. It ALWAYS has those binary components so if you want an Oracle DATE data type then you cannot get it without a time.
The Oracle DATE data type was released with Oracle version 2 in 1979 and predates the ANSI/ISO standard (of 1986, where a DATE does not have a time component) and Oracle has maintained backwards compatibility with their previous data types rather than adopting the ANSI standard.
If you use the TRUNC(date_value, format_model) function then it will set the binary components of the DATE, up to the specified format model, to the minimum (0 for hours, minutes and seconds, 1 for days and months) but it will NOT give you a data type that does not have a time component.
It happens only in perl. I'm getting only date in toad.
No, you are getting the entire 7 byte binary value in Toad; however, the user interface is only choosing to show you the date component. There should be a setting in the preferences that can set the date format in Toad which will let you see the entire date-time components.
Oracle SQL/Plus and SQL Developer use the NLS_DATE_FORMAT session parameter and Toad may also be able to use that.
If you want to get the value as a DATE then it will always have a time component (even if you set that time component to zeros using TRUNC).
If you want to get the date so that it is formatted in a way without a time component then you need to convert it to another data type and can use TO_CHAR to format it as a string:
SELECT TO_CHAR(CREATED, 'YYYY-MM-DD')
FROM DBA_OBJECTS
But then you will be returning a (formatted) string and not a DATE data type.

Power BI DATEADD In Date Calculation Causing Error

In Power BI, I am trying to create a simple new measure column in a table that calculates using the formula below.
TestColumn =
CALCULATE(
SUM(MyTable[MyPrice]),
DATEADD(MyTable[MyDate], -12, MONTH)
)
However, in trying to display this on a table, I receive the error shown below. It appears that there is an issue with my date column.
MdxScript(Model) (28, 5) Calculation error in measure 'TestTable'[TestColumn]: A date column containing duplicate dates was specified in the call to function 'DATEADD'. This is not supported.
However, after testing it on another dataset, it appears to work, which leads me to believe that there is something wrong with the date field that I am bringing in. In the image below, the date column on the left is causing the error, whereas the column on the right works properly.
The column on the right is a date hierarchy, but the one on the left is not. Also worth noting: The data source for the column causing the error originates from an Oracle database, whereas the working one comes from SQL Server. Is there an easy fix to this error that I am receiving? Why is it that one of my date fields works with the formula, but the other does not?
Actually there are duplicate values in your table ( same date in multiple rows ). You are using time intelligence functions DATEADD which in DAX need a separate date table/dimension.
You could create a calendar table with unique and continuous dates that cover all periods of your fact table.

Accessing postgresql's timestamp field from Oracle via ODBC cause a loss of time precision in microsecond

I am trying to access PostgreSQL record from Oracle via ODBC, there is a severe problem when I try to read timestamp field, the precision of time in microsecond has been lost. For example: 2018-01-25 12:40:20.123456 in PostgreSQL will be 2018-01-25 12:40:20.000000 in the Oracle. To make sure, I have write PL/SQL to check the data, somehow all microsecond digits has been lost.
There's a documentation talking about connection string's parameter BTD - BIND TIMESTAMP AS DATE link
By default, this parameter should be "FALSE"
Bind TIMESTAMP as DATE (BTD Connect String)
Added the new connection option, Bind TIMESTAMP as DATE, that allows you to bind the ODBC driver SQL_TIMESTAMP data type to the Oracle DATE data type instead of to the Oracle TIMESTAMP data type (which is the default).
Here is my PL/SQL:
declare
v_timestamp timestamp(6);
begin
select max("MODIFIED_ON") into v_timestamp from "public"."DAS_ITEM"#PG_LINK;
dbms_output.put_line(v_timestamp);
end;
The result is: 19/JAN/18 08:59:42.000000 AM , it's missing microsecond, all 6-digit second fraction has been replace to zero.
On the other hand, on my PostgreSQL, the result is "2018-01-19 08:59:42.695166"
I also have tested with isql, it return timestamp value with whole precision, as a consequence, I believe that the main reason comes from Oracle.
The Oracle DATE datatype does not support fractions of seconds. You need to use TIMESTAMP for that. This also applies to any table columns or PL/SQL datatypes PostgreSQL timestamps go into; if the timestamps are passed into a DATE somewhere, fractions of seconds will be truncated.

Why does CURRENT_DATE contains time in Oracle Mode?

When I connect to
jdbc:hsqldb:mem:lbw;sql.syntax_ora=true
the statement
SELECT CURRENT_DATE FROM dual
results in
2014-01-31 10:35:54
This is in opposite to connections without Oracle syntax mode, where CURRENT_DATE doesn't contain time.
As described in the HSQLDB documentation, DATE is interpreted as TIMESTAMP(0) in Oracle syntax mode. But in Oracle 10g itself, CURRENT_DATE behaves as expected (without time).
This difference seems to include DATE fields in general.
Why does HSQLDB behave this way?
Is there a way to disable the automatic conversion?
From the same HSQLDB documentation you linked to:
Datetime types
HSQLDB fully supports datetime and interval types and operations,
including all relevant optional features, as specified by the SQL
Standard since SQL-92. The two groups of types are complementary.
The DATE type represents a calendar date with YEAR, MONTH and DAY
fields.
The TIME type represents time of day with HOUR, MINUTE and SECOND
fields, plus an optional SECOND FRACTION field.
The TIMESTAMP type represents the combination of DATE and TIME types.
The Oracle compatibility section says:
The DATE type is interpreted as TIMESTAMP(0) in ORA syntax mode.
Oracle's DATE data type "contains the datetime fields YEAR, MONTH, DAY, HOUR, MINUTE, and SECOND". So it's equivalent to an HSQLDB TIMESTAMP(0) data type, and in Oracle mode it is treated as such.
Oracle dates always have a time component, even if it is all zeros for midnight. If your SQL client doesn't show it by default you can see that with select to_char(current_date, 'YYYY-MM-DD HH24:MI:SS'), as others have already pointed out.
In normal non-Oracle mode HSQLDB is just treating the value as an SQL-standard DATE and dropping the time portion; in Oracle mode it preserves the time. There doesn't seem to be any way to selectively enable some aspects of the Oracle mode, so you're stuck with the time - really not sure why that is an issue though since it's just reflecting the data you have in your database. If you want to ignore the time you could always select trunc(current_date), which will take the time back to midnight; but it will still show as 2014-01-31 00:00:00 because it's still going to be treated as TIMESTAMP(0).

Insert a datetime value with GetDate() function to a SQL server (2005) table?

I am working (or fixing bugs) on an application which was developed in VS 2005 C#. The application saves data to a SQL server 2005. One of insert SQL statement tries to insert a time-stamp value to a field with GetDate() TSQL function as date time value.
Insert into table1 (field1, ... fieldDt) values ('value1', ... GetDate());
The reason to use GetDate() function is that the SQL server may be at a remove site, and the date time may be in a difference time zone. Therefore, GetDate() will always get a date from the server. As the function can be verified in SQL Management Studio, this is what I get:
SELECT GetDate(), LEN(GetDate());
-- 2010-06-10 14:04:48.293 19
One thing I realize is that the length is not up to the milliseconds, i.e., 19 is actually for '2010-06-10 14:04:48'. Anyway, the issue I have right now is that after the insert, the fieldDt actually has a date time value up to minutes, for example, '2010-06-10 14:04:00'. I am not sure why. I don't have permission to update or change the table with a trigger to update the field.
My question is that how I can use a INSERT T-SQL to add a new row with a date time value ( SQL server's local date time) with a precision up to milliseconds?
Check your table. My guess is that the FieldDT column has a data type of SmallDateTime which stores date and time, but with a precision to the nearest minute. If my guess is correct, you will not be able to store seconds or milliseconds unless you change the data type of the column.
I would guess that you are not storing the GetDate() value in a DateTime field. If you store the value in a datetime field you will get the maximum precision allowed by the DateTime type. Additionally, DateTime is a binary type (a double actually) so 19 means 19 bytes, not 19 characters.
Try to create a simple table with a Datetime field like this
CREATE TABLE [dbo].[DateTable](
[DateField] [datetime] NOT NULL
)
And add a date with
insert into datetable (datefield) values(getdate())
When you execute a select you will get back a value including milliseconds. The following query
select * from datetable
returns
2010-06-11 00:38:46.660
Maybe this would work instead of getdate -
SYSDATETIME()
look here if you can find what you need -
http://msdn.microsoft.com/en-us/library/ms188383.aspx
As you're on SQL 2005, don't forget the getutcdate() function to ensure that, regardless of where your servers are actually located, you have a constant time reference.
Imagine, you have the server in the UK in winter (i.e. GMT+0), and save a record at 10:30am. You then cut over to a SQL server hosted in California (GMT+8) and 8 hours later save another record.
Using getdate(), both saves record the same time "10:30:00". Using getutcdate(), the first save records at "10:30:00", the second save records "18:30:00".
Not really answering the question, but important in your circumstances.
You can use like this in procedure and If there is no procedure use only getdate().
insert into [dbo].[Tbl_User] (UserId,Uvendoremail,UAddress,Ddob,DMobile,
DEmail,DPassword,DAddress,CreatedDate) values (#userid,#vendoremail#address,#dob,#mobile,#email,#dpassword,#daddress,getdate())

Resources