Convert utc to Central time conversion in the SQL SELECT statement makes my query very slow - user-defined-functions

I have a query which is taking more than 10 minutes to run. I found that the query was slow since there are few functions in the SELECT statement that we are using to convert the UTC to Central Time. I am not able to re-write the existing functions to inline table-valued functions so that I can join the function with other tables. And I am also not able to use 'AT TIME ZONE' since we are using SQL server 2012. Is there any other option to avoid the scalar function in order to convert the UTC time to CST so fast?

Related

Oracle Date to_char Returns Different Results

I have a database on my local development machine and there is a database on our test server. Basically, the tables on my dev machine were copied over from the test machine.
However, I have found a difference in how the same date is treated by the to_char function. On my development machine if I run the following query:
select test_date, to_char(test_date, 'YYYY-MM-DD')
from test.table
where id = 'C0007784'
I get the following results:
31-DEC-99 1999-12-31
On the test server running the same query against the same schema and data I get the following:
31-DEC-99 1899-12-31
Could this difference in behaviour of to_char be due to a setting being different in the two Oracle instances?
If I run SELECT value FROM v$nls_parameters WHERE parameter ='NLS_DATE_FORMAT'; I get DD-MON-RR for both instances.
So you exported the contents of the table to a csv file using DD-MON-YY format. YY obviously causes ambiguity. I guess that when you were importing the file, 99 was interpreted as 1999 instead of 1899. I don't know the exact mechanism which is used by database to guess the full year, but anyway Oracle strongly recommends YYYY in date format:
Note: Oracle recommends that you use the 4-digit year element (YYYY)
instead of the shorter year elements for these reasons: The 4-digit
year element eliminates ambiguity.
The shorter year elements may affect query optimization because the
year is not known at query compile time and can only be determined at
run time.

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).

select condition from cdef$ where rowid=:1 query elapsed time is more

In Db trace, there is a query taking long time.Can some one explain what it means.Seems this is very generic oracle query and not involved with my custom tables.
select condition from cdef$ where rowid=:1;
Found the same query in multiple places in trc files(DB trace) and one among all have huge amount of elapsed time. So, what will be the solution to avoid taking such a long time. Am using 11g version oracle.
You're right, that is an example of Oracle's recursive SQL, the statements it runs against the data dictionary to support our application SQL. That particular statement is the query Oracle runs to get the Search Condition of a CHECK constraint. If you are inserting or updating rows in tables with check constraints you will see it a lot.
The actual statement shouldn't take too long to run, so it is unlikely to be the source of a performance problem. Unless you are running lots of insert statements with hard-coded values. Oracle will run that query every time it parses a fresh insert or update statement. That will get expensive if you're not using bind variables.

"TIMESTAMP WITH TIME ZONE" <--> DateTImeOffset mapping won't deliver the Zone part on INSERT commands (Entity Framework + Oracle)

I use EF (EDMX model - DB first) to map "TIMESTAMP WITH TIME ZONE" to a DateTimeOffset. when I commit the DateTimeOffset to Oracle, the Zone part is saved incorrectly.
So if using the model, for example, to insert the value 29/02/2012 10:10:10 +04:00, the value that is actually stored in Oracle is 29/02/2012 10:10:10 +02:00 (assuming +02:00 is local zone)
Note that the mappings works just fine when querying the data. Only INSERT (via ObjectContext.SaveChanges()) is broken...
I've debugged into the "Oracle.DataAccess.dll" ( using ILSpy :) ) and found that the mapping code for EF omits the zone (the "Oracle Data Provider" passes the DateTimeOffset.DateTime only).
Does anyone know a workaround?
Thanks in advance
Eli
BTW: I am using .net4, EF4, Oracle 11g, ODAC 11.2 Release 4 (11.2.0.3.0)
You could try to dynamicly set the Session Time Zone, which "takes effect when a TIMESTAMP value is converted to the TIMESTAMP WITH
TIME ZONE or TIMESTAMP WITH LOCAL TIME ZONE datatype".
...a terrible hack of course, also because you cannot execute alter session directly through SQL. You'd have to use something like
begin DBMS_UTITLITY.EXEC_DDL_STATEMENT ('Alter Session Set TIME_ZONE = ''+04:00'''); end;
Oracle admitted this was a bug https://community.oracle.com/thread/2360615?tstart=0. And they sad it had been fixed in bug 13851978. But my test on oracle client on 11.2.0.3.0 is still failed.
On solution is as #HAL 9000 suggested setting the session's time zone with the hours and minutes in time span of DatetimeOffset before saving to database. But this won't work if there are multiple DatetimeOffset properties in one object and these properties have different timespans inside Datetimeoffset.
Another alternative is replacing ODP.NET with 3rd-party data provider such as Devart's DotConnect(I've tested this, it works for me). There is a comparison in stackoverflow about different data providers https://stackoverflow.com/a/8298684/1443505.
Storing offsets in the database might not hold good for Daylight savings offset Management.
It will be a good practice to always use timezone names over offset values where the purpose is unaffected.
--To store actual time and timezone value
to_timestamp_tz('10-SEP-2014 01:40:00.000000000 US/Pacific','DD-MON-YYYY HH24:MI:SS.FF9 TZR')
--To store actual time at timezone converted to UTC timezone value for uniformity
to_timestamp_tz('10-SEP-2014 01:40:00.000000000 US/Pacific','DD-MON-YYYY HH24:MI:SS.FF9 TZR') at time zone 'UTC'

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