cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with remote data access to MS SQL Server and different date order setting

VolkerBarth
Contributor
0 Kudos
3,956

I'm running a rather simple query from a v16.0.0.2344 database against a MS SQL Server 2012 R2 database - and to my surprise I get an empty result set although it should return rows.

The query contains a WHERE condition based on comparison with a datetime value, such as

select * from MyRemoteMsView
where datField >= '2016-07-01';

and should return several rows with a date value in the 2nd have of this year.

(It does not matter whether the datetime value is specified via a connection variable or as date literal).

Using CIS_OPTION = 7 I can trace that the statement is passed to the MS SQL Server in full passthrough mode, such as

select t1.* from "MyDatabase".dbo."MyView" t1
where t1."datField" >= '2016-07-01 00:00:00.000'

which looks ok.

However, the statement when directly executed on the MS SQL Server will fail because of our DATEFORMAT (*) setting there (default for German locale = "dmy"), so the query returns a 242 conversion error - basically telling that the varchar value is out of range for a datetime. When I issue "SET DATEFORMAT ymd" on MS SQL Server, the query returns the correct result set.

My questions:

  • Why is the conversion error on the MS SQL Server side not returned to SQL Anywhere? (An error message would have helped to find out that something is wrong, much better than an empty result set)?
  • How can I force DATEFORMAT = ymd via Remote Data Access? I tried to run "FORWARD TO MySqlServer 'SET DATEFORMAT = ymd', and this was successfully, but apparently had no impact on the next remote query.
  • Shouldn't the remote data access layer itself handle different date orders accordingly - or use the ISO8601 representation (here: '2016-07-01T00:00:00.000') which should be recognized independent of the date order setting? (I tried to specify the date literal in that ISO format but it gets passed as '2016-07-01 00:00:00.000' and is therefore rejected, either.)

(*): MS SQL Server's DATEFORMAT setting is comparable to SA's date_order option, but has no connection to SA's dateformat() function.

Accepted Solutions (1)

Accepted Solutions (1)

VolkerBarth
Contributor
0 Kudos

Jack wrote:

Is datField a timestamp column? Perhaps if you cast it to char, then the formatting will be left untouched.

Well, that seems to allow for a workaround at least: When I supply the comparison value as usual timestamp literal or as a timestamp variable and then convert the MS SQL Server datetime column to an international date format style (here 120 for ODBC canonical), the comparison is treated correctly:

select t1.* from "MyDatabase".dbo."MyView" t1
where convert(varchar(30), t1."datField", 120) >= '2016-07-01 00:00:00.000'
order by t1."datField";

I'd consider that a workaround as casting a datetime value won't lead to a sargable condition and might perform bad with a huge table. But in my case, it's sufficient.

Answers (1)

Answers (1)

VolkerBarth
Contributor
0 Kudos

BTW, I had tested with a 16.0.0.2270 database server today, in contrast to 16.0.0.2344 last week (and possibly with a different SQL Server Native Client) - in case that does influence whether the date condition leads to an error or an empty result set...

I have confirmed that: The database itself has just been copied to a test system, so all settings including the remote server definition should be equal. The behaviour differs:

  • Machine 1: Win 2012 R2, SA 16.0.0.2270, MS SQL Server as remote server via SQL Native Client 11: I get a -660 error code.
  • Machine 2: Win 7, SA 16.0.0.2344, MS SQL Server as remote server via SQL Native Client 10: Just an empty result set, no error message.

Further testing revealed:

The different SQL Native Client does not make a difference: I tested Machine 2 with the same version of SQL Native Client 11, and still don't get an error.

However, the initial values listed by CIS_OPTION = 7 for a new connection are slightly different between both machines, with one different entry:

  • Machine 1: Concatenation null behavior = SQL_CB_NULL
  • Machine 2: Concatenation null behavior = SQL_CB_NON_NULL

I have noticed that for Machine 2, the ODBC setting had the "AnsiNPW" set to "No" (I guess as a default). When I cleared that, I got the expected error message.

Conclusion:

So don't use MS SQL Server DSNs with "AnsiNPW=No" when you like to get ODBC errors...