How to stop MS Access from changing my SQL code? - ms-access

I've wrote an SQL query in MS Access and Access made a mess of it, only to show it "graphical".
How do I stop it from doing this?

There's no stopping Access from changing your SQL if you save it as a QueryDef object (ie, using the graphical query editor). You have (at least) two other options:
Build your queries in VBA
Store your queries in a table dedicated to queries using a Memo field to store the SQL (this will also require some VBA to take the SQL and execute it or assign it to a temporary querydef, etc.)
You can still use the QBE (query-by-example) window to generate your SQL initially if you want.
Also, if you have a non-Jet backend (MS SQL Server, for example) you can write pass-through queries. You lose the graphical interface but gain all of the functionality of writing SQL in your backend of choice. Access won't rearrange the formatting on pass-through queries.

Here's a dirty trick : append an UNION at the end of the query which is always FALSE.
SELECT field_1, field_2
FROM my_table
UNION select field_1, field_2 FROM my_table WHERE False = True;
That's horrible and I'm ashamed to do something like that but it works.

Related

How to use local DB table in a pass-through query?

I am currently working on a query in Access 2010 and I am trying to get the below query to work. I have the connection string between my local DB and the server that I am passing through to working just fine.
Select column1
, column2
from serverDB.dbo.table1
where column1 in (Select column1 from tbl_Name1)
In this situation table1 is the table on the server that I am passing through to get to, but the tbl_Name1 is the table that is actually in my Access DB that I am trying to use to create constraints on the data that I am pulling from the server.
When I try to run the query, I am getting the error that it doesn't think tbl_Name1 exists.
Any help is appreciated!
I just came across a solution that may help others in a similar situation.
This approach is easy because you can just run one query on your local Access database and get everything you need all at once. However, a lot of filtering/churning-through-results may be done on your own local computer behind the scenes, as opposed to on the remote server, so it may not necessarily be quick.
Steps
Create a query, make it a "Pass Through" query, and set up its "ODBC Connect Str" property to connect to the remote database.
Write the pass through query, something like SELECT RemoteId From RemoteTable and give your pass through query a name, maybe PassThroughQuery
Create a new query, make it a regular "Select" query.
Write your new query, using the pass through query you just created as a table in this new query (seems weird to use a query as a table, but it works) and join that PassThroughQuery "table" to your local table and filter it based on values in the local table, something like SELECT R.RemoteId, L.LocalValue FROM PassThroughQuery R INNER JOIN LocalTable L ON L.LocalId = R.RemoteId where L.LocalValue = 'SomeText'
This approach allows you to mix/join the results of a pass through query and the data in a local Access database table cleanly, albeit potentially slowly if there is a lot of data involved.
I think the issue is that a pass through query is one that is run on the server. Since one of the tables is located on the local Access file, it won't find the table.
Possible workaround if you must stay with the pass-through is you can build an SQL string with the results of the nested query rather than the query string itself (depending on the number of results this may or may not be practical)
e.g. Instead of Select column1 from tbl_Name1 you use "c1result1","c1result2",....

Error running SQL in MS-Access with ODBC connection to MYSQL

I was helping a non-profit migrate MS-Access data to MYSQL. So, I ported data to MYSQL and created links in ms-access to MYSQL tables using ODBC. Majority of the existing SQL works fine. However I am stumped on this one error -
You have an error in your SQL syntax check the manual that corresponds to your MySQL server version for the right syntax to use near UNION...
I have stripped the SQL with 7 UNIONS to bare bones where it still fails.
(SELECT 1 as A FROM Households H)
UNION ALL
(SELECT 2 as A FROM Households H)
UNION ALL
(SELECT 3 as A FROM Households H)
The part that is getting to me is that I am able to run above successfully as long as I run only one UNION meaning below SQL, but the moment I add a third one, it gives ODBC error
(SELECT 1 as A FROM Households H)
UNION ALL
(SELECT 2 as A FROM Households H)
I tried using ` or ' or [] but none of these helped. The reason I am frustrated with this error is that either it should fail with all or none, it gives an error only when using two or more UNION clauses. Could this be a potential bug in driver?
I am using mysql-64 bit on win-7 64bit with ms-access and a 32-bit driver. It shouldn't be an architecture problem as I am able to run other queries with multiple UNIONs, and accessing the same set of tables.
It would be great if someone can give pointers on how to debug this further.
In my version of Access, when I edit a query in Design (SQL) view there are three buttons at the top. "Union", "Pass-Through", and "Data Definition".
If I click "Pass-Through" your query works. If I click "Union" it breaks. Can you get away with using "Pass-Through" for this query?
Even in "Union" or "Data Definition" mode, this seems to work:
(SELECT 1, column1 as A FROM Households H)
UNION ALL
(SELECT 2, column2 as A FROM Households H)
UNION ALL
(SELECT 3, column3 as A FROM Households H);
Maybe Access is confused by only a single column?
Alternatively, just use a a multiplex table instead of a union:
SELECT mux.id,
IIf(mux.id=1,column1,IIf(mux.id=2,column2,column3)) AS A
FROM Households, mux;
Note: mux table should have 3 values in it 1,2,3. If it has more, you'd want to limit to the first 3 (or n) in a where clause.
It is a known MySQL problem: more than two UNION SELECT statement problem (with MS Access) but I don't know if the problem is in the MSAccess SQL parser (which compiles to ODBC SQL), or in the MySQL ODBC driver (which compiles ODBC SQL to MySQL SQL)
To work it out, I'd have to look at the ODBC log, and the ODBC specification, and see if Access was emmitting valid ODBC SQL.
That would be a waste of effort, since it makes more sense to use a pass-through query anyway. The main reason for using a native MSAccess query in this place would be to join to different data sources - for example, an Excel Spreadsheet and a MySQL table -, and according to the comments on the MySQL bug report, the problem goes away when you do that.
I am not sure about where the problem lies, but I think (though it's only an assumption) that this is on MS Access side. I had two UNION queries, each of them was putting some other queries together. Both used somewhat complicated sub-queries so I had lots of problem to create a pass-through query and I didn't want to use MySQL "views".
Surprisingly one of my queries worked, the other showed an error. My idea is that the working query used some Access features while the other was some kind of SELECT ... FROM's .
I don't know the rules but I think that when your query is simple, Access sends it to external database engine and puts one more bracket and causes an error. If you do a comlicated query, Access gets all data it needs and makes all necessary operations itself. For example, you may try to create a pivot query, that uses MSSQL TRANSFORM statement, which does not exist in MySQL, so it is obvious that Access handles it itself. So why couldn't it make SELECT by itself? I don't know. Maybe some performance reasons?
My working query differed from the other that it had one more (string) field that was calculated by built-in Access function. It used also Access & operator, which has another meaning (logical AND) in MySQL. (By the way to join strings in MySQL use CONCAT function). They of course need to be evaluated by Access, because MySQL does not understand this method of joining strings together.
I suggest just to make UNION not from tables, but from queries (like SELECT * FROM tablename and nothing more) and giving them a field that you don't need but that will force Access to handle the query. So a query (in Access) should look like this:
SELECT tablename.*, [somefield1]&[somefield2] AS useless_field FROM tablename;
(in my Access 2000 operations like "a" & "b" or IIf(true;true;false) were probably simplified and solved, so it didn't work. I think one needs at least one dynamic field to evaluate. I also did no performance tests. Probably it would be fastest if you add to integers, maybe just increase your index by 1?).
Then, of course, you join it together:
SELECT * FROM query1
UNION ALL
SELECT * FROM query2
UNION ALL
SELECT * FROM query3
UNION ALL
...
SELECT * FROM queryn
;
You don't need this useless_field of course.
I agree that this is a workaround but I have no other ideas.

Union query Access on an Interbase DB

I am executing queries from Access 2010 on an Interbase database via ODBC (Easysoft) ver.7. Everything works fine except when i come to fire a Union query such as this:
SELECT TRIP.TRIPDATE, RESERVATION.BOOKINGREF, RESERVATION.LEADNAME, TRIP.DRIVERID, RESERVATION.STATUS, RESERVATION.DATECANCELLED, TRIP.TRANSPORTTYPEID
FROM TRIP INNER JOIN RESERVATION ON TRIP.TRIPID = RESERVATION.ARRIVALTRIPID
WHERE (((TRIP.TRIPDATE) Between #2/1/2012# And #2/29/2012#) AND ((TRIP.DRIVERID)=2) AND ((RESERVATION.DATECANCELLED) Is Null) AND ((TRIP.TRANSPORTTYPEID)=12))
UNION
SELECT TRIP.TRIPDATE, RESERVATION.BOOKINGREF, RESERVATION.LEADNAME, TRIP.DRIVERID, RESERVATION.STATUS, RESERVATION.DATECANCELLED, TRIP.TRANSPORTTYPEID
FROM TRIP INNER JOIN RESERVATION ON TRIP.TRIPID = RESERVATION.DEPARTURETRIPID
WHERE (((TRIP.TRIPDATE) Between #2/1/2012# And #2/29/2012#) AND ((TRIP.DRIVERID)=2) AND ((RESERVATION.DATECANCELLED) Is Null) AND ((TRIP.TRANSPORTTYPEID)=12));
When I run this query from Access I get
"ODBC --call failed, [Easysoft][Interbase]Dynamic SQL Error, SQL error
code = -104, Token unknown -line1,char 0, ((#-104)"
When running the select queries on their own they work fine but when joined via UNION I get this error.
Any help would be appreciated.
thanks
You don't mention if your query is a passthrough query or if you are using linked ODBC tables in an Access query.
If you are using a normal Access query
When using linked ODBC tables in a normal Access query, the Access data engine will rewrite the queries as necessary to make them compatible with the other database engine.
Sometimes, it can fail though.
Make sure each SELECT query works and returns correct data independently.
Try a simpler UNION query to make sure that the issue comes from the UNION keyword itself.
Try UNION ALL
Try using a pass-through query instead.
If you are using a pass-through query
Pass-through queries are send verbatim to the ODBC engine, and Access just collects the results without rewriting the query itself.
Make sure each SELECT query works as a pass-through query and returns correct data independently.
Make sure that the literal dates are properly formatted for Interbase SQL.
The ones you use are correct for Access SQL, but different databases accept different formats.
Try a simpler UNION query using simple SELECT statements involving 1 or 3 fields only.
Try UNION ALL.
You don't show it in your question, but just in case, if you used an ORDER BY statement, you have to wrap the UNION query.
Try to cast the data types of your fields. It may be that some fields's data are incorrectly interpreted and that the union fails because it assumes that the data retrieved is of different types.
Try using a standard Access query instead.

How to append data from an Access table to a SQL server table via a pass-through query?

It seems like it's only possible to use a pass-through query to retrieve data from your SQL Server tables and into MS Access. But how about the other way? From an Access table to a SQL server table.
What are my options from within MS Access when I need high performance? (The normal approach of having an append query that appends to a linked table is simply too slow)
In an pass-through query I cannot reference MS Access tables or queries, and therefore my INSERT INTO statement cannot work. Is there a work around via VBA?
You can use OPENROWSET in a passthrough query.
SELECT id,
atext
INTO anewtable
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'z:\docs\test.accdb'; 'admin';'',table1);
You may need some or all of these options:
sp_configure 'show advanced options', 1;
RECONFIGURE;
GO
sp_configure 'Ad Hoc Distributed Queries', 1;
RECONFIGURE;
GO
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0',
N'AllowInProcess', 1
GO
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0',
N'DynamicParameters', 1
GO
I doubt that it will be any faster.
It is possible in Access to use a macro to dynamically create the pass through query definition using SetValue (I think this is called SetProperty now). Basically you can update the query definition for an existing pass through query, then run it. I did this once and it was a lot faster, but that was a long time ago. I may have had a piece of VB that cycled through a table to create the query.

Whats the Efficient way to get data from db using LINQ To SQL or LINQ To Entities?

When you run Linq to Sql or Linq to Entites to get a list of records it runs query to select all fields from a table. Is it an efficient solution. Lets say: I run this LINQ
dim lstCustomers = from c in db.Customers select c
it run query to get all fields from a table whether i need all fields or not. I am using asp.net with MVC so should i write this query in view (where i only need CustomerID and name)
dim lstCustomers = from c in db.Customers _
select new Customer with { c.CustomerID, c.Name }
If i have to use 2nd query then whats the advantage of LINQ and Entity Framework. This thing i can do with SQL query (with different syntax)
Anyone can help?
First of all, LINQ queries are evaluated lazily. That means that single line doesn't do anything but itself, so I assume you actually iterate the results with For Each.
The answer to your first question is yes, all fields are retrieved from the database with the first statement.
Yes, but in order to use SQL directly, you'll have to manually create entity classes, manually retrieve data using SqlDataReader or something to achieve the level of abstraction LINQ provides in that line. That's lots of more work on your behalf. With LINQ to SQL, you don't even need to explicitly write code to open a connection to database.
actuly linq have different sets of advantages over writing normal writing sql queries:
if you wrote sql queries then overloaded steps:
1. you need a sql connection class
2. you need a sql command or sqldataadapter.
3.then you need a container like datatable and dataset.
so while using linq you dont need all those steps. just write the queries as you wrote above.
also incase you wrote something incorrect in your sqlquery then there is no compile time error. error only generates when you execute the query during runtime.
but unlike sql queries, linq provides you the compile time error.
also linq is best of strongly type collections.