Comparing dates from SQL Server linked table in Access - sql

I have a SQL Server linked table in Access and I am trying to query to extract from a certain date or data ranges (i.e. < 01/31/2017, for example). I tried in the criteria in Access design mode, the following: < #01/31/2017# but it is not comparing correctly.
The field in the SQL server table is datetime data type, I formatted it in Access as Short Date in the properties in design mode.
SELECT dbo_LicensesLiveViewWithRevenue.BAN,
dbo_LicensesLiveViewWithRevenue.PTN,
dbo_LicensesLiveViewWithRevenue.SOC,
dbo_LicensesLiveViewWithRevenue.LicenseCreatedOn,
Format([DeactivationDate],"Short Date") AS DeactOn,
dbo_LicensesLiveViewWithRevenue.RetailPrice,
dbo_LicensesLiveViewWithRevenue.WholeSalePrice,
dbo_LicensesLiveViewWithRevenue.AccountID
FROM dbo_LicensesLiveViewWithRevenue
WHERE (((dbo_LicensesLiveViewWithRevenue.LicenseCreatedOn)< #2017/01/31#)) ORDER BY dbo_LicensesLiveViewWithRevenue.LicenseCreatedOn;
I also tried the query with passing the dates as parameters from a form, with no luck.
SELECT dbo_LicensesLiveViewWithRevenue.BAN,
dbo_LicensesLiveViewWithRevenue.PTN,
dbo_LicensesLiveViewWithRevenue.SOC,
dbo_LicensesLiveViewWithRevenue.LicenseCreatedOn,
Format([DeactivationDate],"Short Date") AS DeactOn,
dbo_LicensesLiveViewWithRevenue.RetailPrice,
dbo_LicensesLiveViewWithRevenue.WholeSalePrice,
dbo_LicensesLiveViewWithRevenue.AccountID
FROM dbo_LicensesLiveViewWithRevenue
WHERE (((dbo_LicensesLiveViewWithRevenue.LicenseCreatedOn)<[Forms]![MainForm]![EndDate]));
The results:
When I run the query directly in SQL server is giving me the correct records with correct dates (in SQL the dates are < '20170131'). In Access I have the same count of records but the dates are showing wrong as in the result pictures.

I would suggest that you open the linked table in design view. Ignore the prompt msg about this action being read only).
If the columns in question are newer date time formats (datetime2), and you link using the standard SQL driver, then such date are seen as TEXT columns, and NOT date/time.
A quick look at the linked table in design view will revel if the columns are seen by access as date or text columns.
If you are using any newer format dates from SQL server, you MUST use the newer native 11 (or later) drivers when you link tables to SQL server. It is for this reason that I tend to stick with the older “default” legacy SQL driver. The legacy drivers are installed and included with windows - and thus no install of drivers is required when you run Access on each workstation.
However, if you are using newer date formats in SQL server, then you need to link the tables using the native 11 drivers, and you ALSO have to distribute and install the native 11 drivers on each workstation in addition to Access (or the Access runtime). So while one should prefer and use the newer SQL drivers, the downside is these drivers have to be installed on each workstation.
So double check the data type for those columns that Access shows in table design mode – if they are text, then you need to re-link with the native 11 drivers.

Related

Result set differences in a SQL Server Compact database PC vs Mobile device

Interesting problem: I have a SQL Server CE 3.5 database with some data in it. I run a query on the database, using a mobile device and obtain a result set.
This works fine 99% of the time, but on occasion I get records in the database where the query returns an empty result set.
If I take a copy of the same database file from my mobile device and connect to it with Query analyzer, then run the exact same query (as copied/pasted from the debugger), the query returns records. The query itself does a JOIN and GROUP BY on two tables by a referential identity key field.
Now if I make a clone the same records involved via a series of:
INSERT INTO MyTable (EntireFieldListExceptForIDKey)
SELECT
(EntireFieldListExceptForIDKey)
FROM
MyTable
WHERE
IDKey = Original
The query is now able to correctly assemble a result set on the cloned records on the mobile device.
Can anyone explain this, and possibly how to detect/overcome?
This is most likely due to a corrupt index, as both copying the file to your desktop and creating a new table will cause an Index rebuild.
It is recommended to regularly Compact your database to prevent this - also make sure you are using the latest runtime binaries.

Generic SQL that both Access and ODBC/Oracle can understand

I have a MS Access query that is based on a linked ODBC table (Oracle).
I'm troubleshooting the poor performance of the query here: Access not properly translating TOP predicate to ODBC/Oracle SQL.
SELECT ri.*
FROM user1_road_insp AS ri
WHERE ri.insp_id = (
select
top 1 ri2.insp_id
from
user1_road_insp ri2
where
ri2.road_id = ri.road_id
and year(insp_date) between [Enter a START year:] and [Enter a END year:]
order by
ri2.insp_date desc,
ri2.length desc,
ri2.insp_id
);
The documentation says:
When you spot a problem, you can try to resolve it by changing the local query. This is often difficult to do successfully, but you may
be able to add criteria that are sent to the server, reducing the
number of rows retrieved for local processing.
In many cases you will find that, despite your best efforts, Office Access still retrieves some entire tables unnecessarily and
performs final query processing locally.
However, it's occurred to me that I don't really understand what sort of SQL I should be writing to make both Access and ODBC/Oracle happy.
Should I be writing some sort of generic SQL that Access can understand in a local query AND that can be easily translated to ODBC/Oracle SQL? Is generic SQL a real thing?
What kind of SQL does the ODBC driver use? It depends as typically MS Access has three types of external data connections that interfaces with different SQL dialects each with the ODBC API.
Linked tables that acts like local tables but are ODBC connected data sources and not stored locally. Once they are incorporated in an Access app, these tables can only use MS Access' SQL dialect. They can be joined with local or even other backend tables from other sources.
Hence, why TOP is available in MS Access and not Oracle. You are essentially using Access SQL to manipulate Oracle data. ODBC serves as the origin point of data while Access' Jet/ACE SQL engine does the processing and resultset viewing in cached memory.
Pass-through queries that do not see local tables or anything else in local app's environment. Such queries use the SQL dialect of the connected database here being Oracle.
Hence, why TOP is NOT available in Oracle and double quotes are allowed in column identifiers. Such quoting would fail in MS Access. Essentially, you are using Oracle SQL to manipulate Oracle data in an Access app. You can take the output of the sqlout.txt log and run it in a pass-through query ODBC-connected to your Oracle database.
ADO/DAO Recordsets that are run entirely via code such as VBA and are direct connections to data sources and uses the connecting database's dialect.
Here, you using Oracle SQL to manipulate Oracle data in an Access app via the ODBC API.
In each one of these types, you will have to connect to a backend ODBC data source. You do not even need to use the GUI but can use Access' object library to create linked tables (see DoCmd.TransferDatabase) and pass through querydefs (see QueryDef.Connect or .Execute).
I suspect the sqlout.txt log you see are translations of the ODBC calls to its native dialect.
To build on #Parfait's point #1:
From Microsoft Access Developer's Guide to SQL Server by Mary Chipman and Andy Baron:
Optimizing Access Queries:
There's a common misconception that the Jet engine always retrieves all the data in linked SQL Server tables and then processes the data locally. This is not usually true. Jet is perfectly capable of sending efficient queries to SQL Server over ODBC and retrieving only the rows required. However, in some cases, Jet will in fact be forced to fetch all the data in certain tables first and then process it. You should be aware of when you are forcing Jet to do this and be sure that it is justified. The following are some general guidelines to follow when creating your Access queries:
Using expressions that can't be evaluated by the server will cause Jet to retrieve all the data required to evaluate those expressions locally. The impact of using Access-specific expressions, such as domain aggregate functions, Access financial functions, or custom VBA functions will vary depending on where in your query the expressions are used. Using such an expression in the SELECT clause will usually not cause a problem because no extra data will be returned. However, if the expression is in the WHERE clause, that criterion cannot be applied on the server, and all the data evaluated by the expression will have to be returned.
With multiple criteria, as many as possible will be processed on the server. This means that even if you use criteria that you know include functions that will need to be processed by Jet, adding other criteria that can be handled by the server will reduce the number of records that Jet has to process. Adding criteria on indexed columns is especially helpful.
Query syntax that includes an Access-specific extension to SQL, not supported by the ODBC driver, may force processing to be done on the client by Access. For example, even though SELECT TOP 5 PERCENT is now supported by SQL Server, it is not supported by the ODBC driver. If you use that syntax in an Access query, Jet will need to retrieve all the records and calculate which ones are in the top 5 percent. On the other hand, even though crosstab queries are specific to Access, Jet will translate them into simple GROUP BY queries and fetch just the required data in one trip to the server unless problematic criteria is used.
Heterogeneous joins between local and remote tables or between remote tables that are in different data sources will, of course, have to be processed by Jet after the source data is retrieved. However, if the remote join field is indexed and the table is large, Jet will often use the index to retrieve only the required rows by making multiple calls to the remote table, one fore each row required.
Jet allows you to mix data types within [typo - fix later] of UNION queries and within expressions, but SQL server doesn't. Such mixing of data types will force processing to be done locally.
Multiple outer joins in one query will be processed locally.
The most important factor is reducing the total number of records being fetched. Jet will retrieve multiple batches of records in the background until the result set is complete, so even though you may seem to get results back immediately, a continuing load is being placed on the server for large result sets.
Note: this book is quite old (published in 2000) and is in reference to Jet Engine. I imagine things might be slightly different in newer versions of Access which use ACE, although I don't have a source to back this up.

MS - Access BigInt SQL SERVER Issues

I have an access database that we use for simple reporting solutions, this pulls data from a remote data base through an ODBC link. The data-warehouse provider has recently added a new data field to all of their tables which is formatted as a 'BIGINT'
Access now shows all records as deleted as it cannot deal with the BIGINT linked table.
As the data warehouse will not change their tables is there anyway that I can get the MS-Access to display correctly and ignore the 'BIGINT' field in the table linking?
I am having to work around this at this moment in time by copying the entire data warehouse minus this column to a MYSQL DB daily which is far from ideal...
I cannot for the life of me work this out.
Instead of using a linked table, just write a passthru query in Access. Eventually CONVERT your BigInt into a string or Integer, depending on the contents.
This link suggests loading the data into a local table with a data type of string:
http://social.msdn.microsoft.com/Forums/office/en-US/fb6f99ec-2ed7-487b-ba39-0777a0b44d5f/the-bigint-problem?forum=accessdev
Perhaps consider that MS Access's usefulness is limited here and it may pay to use SQL Server in future as you will continue to run into these kinds of problems. Is there any reason you can't use the datawarehouse directly?
You may also wish to consider using an .ADP (a file type of MS Access) which has a native OLE DB connection to the SQL Server database (no ODBC flimflammery) but also all the usual forms and reports.
ADP's are deprecated but I have had great success with them.
This is an old thread, but you can create a view and cast the bigint as int, and then Access will link to it.
Greg
This is an old thread but:
Casting your bigint as an int as someone has suggested isn't going to work if any of your values in your bigint column are bigger than the maximum value for an int (and if none of them are bigger than the max value for an int, it makes you wonder why a bigint is being used in the first place).
MS Access (from Access 2000 onward) does have a decimal data type, which is good for numbers of up to the maximum size of a SQL Server bigint and more. So if you make your MS Access field to be of type decimal, it can handle anything a SQL Server bigint can throw at it. In your process of taking the data from the SQL Server database into your MS Access database you would need something done programatically along the way to slurp your bigint values from SQL Server and squirt them into MS Access as decimal

Access Date Filters on Linked Tables Fails - Data type mismatch in criteria expression

I have an Access 2013 application where I have linked tables to an outside database, in this case it is Firebird SQL database.
The table in question is actually a Firebird SQL view. In this view I have a column that is stored as a database DATE type. From this access linked table, I created a datasheet view.
The problem I am facing is when a user attempts to filter this date column by the Today, Tomorrow and Yesterday date filters that are offered in the column header.
Attempting to filter nets this error message:
Data type mismatch in criteria expression
Debugging the ODBC connection to expose the SQL statements used on the connection does not show any SQL level filtering, so I assume it is happening in application. Other questions seem to indicate an issue with the escaping of the dates, but I'm not generating a SQL Query at all. Just trying to use the Date Filters offered in Access out of the box.
Everything other than Today, Yesterday, Tomorrow work just fine.

UNDEFINED data type when reading SQL database from Lotus Notes using ODBC: nvarchar

This is the second time it happens to me and before modifying a 3rd party Database structure I wanted to know if anyone knew a better solution:
I'm accessing a MS SQL Server 2008 from a Lotus Notes Agent (Notes 7) to retrieve some data. I use LSXODBC and my "Select" statement works perfect... Except that my agent cannot "understand" Nvarchar SQL Field types. Any other data types work ok (can get the values from number and dates fields without a problem).
It took me a while to figure it out, and I couldn't find a solution (other than modifying the field types on the SQL table to Varchar instead of nVarchar)
I could replicate this both in MS SQL 2005 and 2008.
Last "elegant" solution was to create an SQL view -instead of modifying table structure- with the varchar types instead of nvarchar. Works ok but I have to create a view for each table I'm retrieving data from.
I tried to set the Field type using FieldExpectedDataType Method but didn't work. Still got a DB_TYPE_UNDEFINED.
I thought there might be some configuration issues? or maybe I'm using an old LN Version / ODBC Driver version?
Any hint would be greatly appreciated.
Thank you in advance.
Diego
An old ODBC driver may not support unicode. It was not added until SQL Server 2000 (I'm fairly sure)