Uniform SQL Date in Oracle SQL and SQL Server - sql-server

Like the title indicates, I'm trying to make an uniform query, which has compatible syntax for Oracle SQL and for SQL Server
The current syntax I have is written in Oracle and is:
SELECT *
FROM TableA
WHERE CREATION_DATE = TO_DATE('12-09-2015', 'DD-MM-YYYY')
When I try to build this in SQL Server, this doesn't work. The syntax of SQL Server is
SELECT *
FROM TableA
WHERE OrderDate='12-09-2015'
But this doesn't work in Oracle SQL...
So what is the uniform way to write this?

I am not sure if SQL Server supports ANSI DATE literal, but it is supported in Oracle. The default string literal format is YYYY-MM-DD.
DATE '2015-09-12'
so, if ANSI standard is supported in SQL Server too, then use it. It is simple.
Based on this link, I think you could use the above in both the databases.
WHERE OrderDate='12-09-2015'
Never do that. You are comparing a DATE with a STRING, you might be just lucky to get correct data depending on your locale-specific NLS settings. But, never rely on implicit data type conversion.

Use this for something which works on both:
CAST('2015-09-14' as date)
The cast is executed only once so has no effect on performance.

Related

SQL Server: Using date in ISO 8601 format in WHERE clause

In SQL Server 2014 I tried the following query:
select *
from MyTable
where StartDate = '2021-12-31T00:00:00.0000000'
I get this error:
Msg 295, level 16, state 3, row 3
Conversion failed when converting character string to smalldatetime data type.
As far as I can tell this string is in ISO 8601 format, so it should be accepted by SQL Server (I read that this should actually be the preferred format when passing dates to SQL Server).
Is there a way to tell SQL Server to accept this format?
Please note: this query is actually generated by Linq in an Entity Framework Core DataContext, so I can't change the query itself in any way.
Older versions of EF Core did not support smalldatetime.
This was fixed in version 2.2.0 in 2018.
Update your EF Core version to something more recent than 2.2.0.
If you are using a modern EF Core version, then you should file this as a regression bug.
But better yet: don't use smalldatetime in your database design in the first place. Use datetime2(n) or some other appropriate type instead.
There is no good reason for using smalldatetime in a new database design (nor other types like text, ntext, image, timestamp, etc)
And you should be able to run ALTER TABLE to change the column type to datetime2(7) with no compatibility issues unless something else is really horribly designed in your system, in which case you should fix that.
If you really need to expose data as smalldatetime because of some horrible and opaque, but business-critical, binary that you can't rebuild then you can add a VIEW, SYNONYM and other shims to transparently convert datetime2(n) to smalldatetime while the rest of the system can live in modernity.

Date format changed on imported SQL Server DB

I have migrated a SQL Server database from one server to another. I did this via export to BAK and then Restore on the new machine.
Seems to be a different format somewhere, as a simple query that was working previously, is now throwing an error, but I cannot see what it might be (collation and 'containment' info seem the same).
The old SQL Server version: Microsoft SQL Server 2012 - 11.0.6598.0 Express Edition
The new SQL Server version: Microsoft SQL Server 2019 - 15.0.2080.9 Express Edition
The error, below, refers to a date format:
SELECT userID FROM tblLogin
WHERE CAST('30/09/2021 00:52:14' AS datetime) < DATEADD(n,600,accessDate)
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
(Column accessDate is of type datetime, null)
Always always ALWAYS use the ISO-8601 date formats for literals in Sql Server. For historical reasons, the preferred option for date-only values is different than date-time values, so you want either yyyy-MM-ddTHH:mm:ss for date and time or yyyyMMdd for date-only. But the really important thing is always go in order from most significant (year) to least significant (second).
Anything else isn't really a date literal at all: it's a string you must convert to a date.
If we follow this correct convention (because anything else really is incorrect), you get it down to this (which doesn't even need the CAST() anymore, because Sql Server can interpret it as datetime from the beginning):
SELECT userID
FROM tblLogin
WHERE accessDate > DATEADD(n, -600, '2021-09-30T00:52:14')
Also note I inverted the check, moving the DATEADD() function to act on the literal, instead of the column. This is always preferred, because it can work with any index you may have on the accessDate column. The original code would have rendered any such index worthless for this query.

SQL Server 2019 CHARINDEX returns weird result

When I run the following query in SQL Server 2019, the result is 1, whereas it should be 0.
select CHARINDEX('αρ', 'αυρ')
What could be the problem?
As was mentioned in the comments it may be because you have not declared your string literals as Unicode strings but are using Unicode characters in the strings. SQL Server will be converting the strings to another codepage and doing a bad job of it. Try running this query to see the difference.
SELECT 'αρ', 'αυρ', N'αρ', N'αυρ'
On my server, this gives the following output:
a? a?? αρ αυρ
Another issue is that CHARINDEDX uses the collation of the input which I think is probably not set correctly in this instance. You can force a collation by setting it on one of the inputs. It is also possible to set it at the instance, database and column level.
There are different collations that may be applicable. These have different features, for example some are case sensitive some are not. Also not all collations are installed with every SQL Server instance. It would be worth running SELECT * from sys.fn_helpcollations() to see the descriptions of all the installed ones.
If you change your query to this you should get the result you are looking for.
SELECT CHARINDEX(N'αρ' COLLATE Greek_BIN, N'αυρ')

MS Access Date() syntax in query to SQL Server

I have found several posts on using the GETDATE() function for SQL Server linked table while in an Access front-end VBA procedure. Those posts are focused on the WHERE clause of the query, but I have been unable to find corresponding information on use of GETDATE() for column assignment.
For example, I understand that in the WHERE clause, I would use something like this:
WHERE MyDate = CAST(GETDATE() AS DATE)
However, I am getting syntax errors in VBA when I try to assign the current date to a column, like this:
INSERT INTO MyTable ( SomeValue, TheDate ) SELECT 'Widget' AS Expr1, CAST(GETDATE() AS DATE) AS Expr2;
In this example, TheDate is defined as DateTime in SQL Server. Written like this, VBA reports "Syntax error (missing operator) in query expression 'CAST(GETDATE() AS DATE)'. I tried to surround the expression with Access-friendly # date delimiters, but no luck there.
After spending about 30 minutes searching stackexchange.com various ways for MS Access Date() in SQL, I have been unable to find this. However it is so simple I am sure it was already answered somewhere.
In MS Access you likely (not 100% sure for linked SQL, you have to experiment) should use Now() and Date() functions. First one is equivalent to getdate() in SQL, the second one returns current date without time.
If you run this in Access on a linked table (not a PT query), it should read:
INSERT INTO MyTable ( SomeValue, TheDate )
VALUES ('Widget', Date());
There seems to be some confusing here. If you building a Access query, then ZERO ZERO of the SQL server date functions and syntax matter. Your SQL MUST continue to be written to Access standards unless you using a pass-though query.
However, I seen this 100x times here.
What is the data type on sql server side?
Is it datetime, or datetime2?
And double, triple, qudadropes, (and more) check the linked table in desing mode.
If you link to SQL server using the standard legacy "SQL Server" driver. The one that been shipped for 20 years since windows 98SE?
You MUST check if Access is seeing those columns as text, or as date columns (which in Access always allow a time part if you want).
Access code, queries, forms and EVERYTHING should require ZERO changes if you migrate that data from Access to SQL server and link the table. Again: ZERO ZERO changes.
However, if you used datetime2 on the SQL server side? Then you CAN NOT use the legacy "SQL server driver" when linking table. The reason is they don't support the newer datetime2 format. As a result, Access will actually see, use, and process that column as a text column. You REALLY, but REALLY do not want that to occur.
Why?
Becuase then you spend the next week asking questions on SO about how some date code or column or query does not work.
again:
ZERO ZERO changes are required in Access. If your dates are starting to break, then the issue is not date formats, but that column is now being seen by access as a TEXT data type.
Soltuion:
Either change the sql side datetime2 columns to datetime, and re-link.
or
re-link your tables using a newer native 11 (or later - up to 18 now). that way, access will see/use/process the datetime2 as a correct date format in Access.
So, before you do anything? Open one of the Access tables linked to SQL server in design mode. (ignore the read only prmompt). Now, look at the data type assigned to the date columns. If they are text, then you have a royal mess.
You need to re-link using the newer ODBC drivers.
Zero of your existing code, sql and quires should be touched or even changed if you using a linked table to sql server. But then again, if you linked using the wrong SQL ODBC driver, then Access cannot see nor process those datetime2 columns as date - it will be using text, and you beyond really don't want to allow that to occur.
In summary:
Any date code, SQL updates, sorting, query, VBA code, form code, reports should continue to work with ZERO changes. If you are making changes to dates after a migration, then you done this all wrong, and those date columns are not being seen by access as date columns.
Either get rid of all datetime2 columns and then re-link (change them server side to datetime). Or re-link the tables using a native 11 or later ODBC driver. Either of these choices will fix this issue.
This is a fix that requires ZERO code, and zero changes to Access dealing with dates.

Access DB type mismatch with SQL server

I have migrated an Access database to SQL server. Many of my "dates" were stored in the Access database in the format "DD/MM/YYYY". However, I notice the SSMA has updated all date columns to the format "DD-MM-YYYY HH:MM:SS". What type should we choose in SQL Server to accomplish the same? The thing that is I want to keep it this way as else we need to change the underlying code.
Much appreciated for your help!
According to this http://social.msdn.microsoft.com/Forums/en-US/4920b4f5-6855-4855-96a9-43f9365d63a0/change-sql-server-date-format the format SQL Server stores datetime fields is generic. You can convert the datetime fields and convert it to varchar in order to show the formal you want.
For example this
convert(varchar, datimefield, 103)
will convert the datetime field using the format 'dd/mm/yyyy'
You should be able to use the date datatype to not store the time, as according to This Link, but only in 2008 or 2012
I checked if it works as such on my SQL Server 2008, and it does.
This will still show it with a dash rather then a slash and in the order YYYY-MM-DD though.

Resources