WHERE clause not working in SQL-query using mdbtools
Asked Answered
S

3

6

I've been working on a project using the LAMP server that requires frequent read of the MS-ACCESS database, stored in *.mdb file. The database has one table and about 40.000 rows in it.

I've installed mdb-tools and configured unixODBC to use it. First impression was positive:

SELECT * FROM [Table]

Worked fine, however returned a huge structure, that overflew my buffer and the tail of data was truncated.

SELECT [col1], [col2], [col3] FROM [Table]

Worked fine as well, but the amount of data was still on the edge of usability (barely didn't exceed the buffer). So I've tried to limit result with the WHERE statement, but neither

SELECT * FROM [Table] WHERE [col1]=X
nor
SELECT * FROM [Table] WHERE [col2] LIKE 'xxx'
nor
SELECT [col1], [col2], [col3] FROM [Table] WHERE [col1]=X
nor
SELECT [col1], [col2], [col3] FROM [Table] WHERE [col2] LIKE 'xxx'

isn't working. They just return empty structure. But if the condition is all-matching - it works:

SELECT * FROM [Table] WHERE [col2] LIKE '%'

returned that huge bulk of data

I know that mdb-tools is quite an ancient solution, that provides read-only access - but that's ok for me. I just want it to work. I've tried both versions - from sourceforge and from github.

Shut answered 9/4, 2013 at 7:38 Comment(4)
Your statement seems allright, and actually you don't get an error. When you do a condition like : "WHERE [col2] LIKE '%'" or "WHERE [col2] LIKE '*'", do you get any results ?Azal
yes, forgot to mention that I've tried them and they work fineShut
Is this .mdb file an active (i.e., not static or archival) database that resides on a Windows machine somewhere?Elisabethelisabethville
yes it is, I have a mounted shared directory on the machine I'm working onShut
E
3

If col1 is a text column then use ... WHERE [col1] = 'some text' (note the use of quotes) for an exact match.

... WHERE [col1] LIKE 'xxx' is equivalent to ... WHERE [col1] = 'xxx'.

When using LIKE the wildcard character % matches zero or more characters, and _ matches one character, so

... WHERE [col1] LIKE 'To%'

should match "Toronto", "Tokyo", "Toledo", etc. ...

Edit

The man page for the mdb-sql command of MDB Tools does claim to support LIKE, so I put together a test .mdb file with a table named [Clients] that contained

ID  LastName    FirstName       Email
--  ----------  --------------  ------------------
1   Thompson    Gord            [email protected]
2   Loblaw      Bob             [email protected]
3   Kingsley    Hank            [email protected]
4   Thompson    Hunter S.       [email protected]

I did sudo apt-get install mdbtools on my test server (Ubuntu 12.04.02), uploaded the .mdb file and did the following

gord@pingu:~$ mdb-sql -p ~/ubuTest2003.mdb
1 => SELECT ID, LastName FROM Clients
2 => go

ID      LastName
1       Thompson
2       Loblaw
3       Kingsley
4       Thompson
4 Rows retrieved
1 => SELECT ID, LastName FROM Clients WHERE LastName LIKE 'Thomp%'
2 => go

ID      LastName
1       Thompson
4       Thompson
2 Rows retrieved

If you are having difficulty with WHERE clauses I would suggest running a similar test (with a small sample dataset) on your system using mdb-sql to see if WHERE clauses work in that context. If they don't work, then your MDB Tools is broken. If they do work, then we'll need to investigate further.

Edit

I spent some time trying to recreate this issue in PHP on my Ubuntu 12.04 test server. I was unable to do so, only because I was unable to get the odbc_ functions in PHP to work with mdbtools at all. I could establish a "valid" connection (no errors) and I could "execute" a query (again, no errors), but I could not get any query to actually return results, not even SELECT * FROM Clients.

In searching for assistance with my problem I happened upon the Stack Overflow article here, which further discouraged me from pursuing the matter further.

Instead, since this is apparently an active Access database hosted on a Windows machine, I personally would opt for using ODBTP. It is a free (GPL) TCP/IP protocol that allows you to pass queries to a Windows machine, which then submits the query via its ODBC driver and passes the results back to you.

It does require that a service be installed and run on the Windows machine, and the PHP client component must be compiled on Linux boxes, but if those requirements aren't too daunting then it is a pretty robust solution to this type of problem. (I have used it a few times in the past.)

And while it is true that ODBTP hasn't been updated for several years, it still works: I tested it just now with my LAMP server running the following PHP script to query an .mdb file residing on my older Vista notebook:

<?php
echo '<html><body><pre>';
echo "ODBTP test:\n";

$con = odbtp_connect('192.168.1.254', 
        'DRIVER={Microsoft Access Driver (*.mdb)};DBQ=c:\\__tmp\\ubuTest.mdb;UID=admin;PWD=;');
if (!$con) die('_connect error: ' . odbtp_get_error($con));
$rst = odbtp_query("SELECT * FROM Clients WHERE LastName LIKE 'Thomp%'");
if (!$rst) die('_query error: ' . odbtp_get_error($con));
while ($row = odbtp_fetch_assoc($rst)) {
    echo $row['ID'] . ': ' . $row['LastName'] . "\n";
}
echo '</pre></body></html>';

The results as displayed in my browser window are

ODBTP test:
1: Thompson
4: Thompson
Elisabethelisabethville answered 9/4, 2013 at 8:0 Comment(5)
Yeah, I do know it. Using wildcards doesn't help. (according to my understanding 'z%' should match 'z40072' or 'OPER%' should match 'OPERATOR')Shut
@Shut So you're saying that (1) LIKE '%' returns all rows, but LIKE 'x%' returns none (assuming there's at least one entry that starts with 'x'), and (2) WHERE [col1] = 'xyz' fails to return any rows when you know that at least one row exists with 'xyz' in [col1]? If so, then your installation of MDB Tools and/or unixODBC may simply be broken.Elisabethelisabethville
Exactly. As I said - I've tried 2 different versions of mdb-tools, so I assume it's not very likely that both of them are broken...Shut
I've checked it - mdb-sql works fine, LIKE and WHERE clauses give expected results. However as I managed to find out, libmdbodbc.so doesn't make use of mdb-sql application, so it's possible that some functionalities were added to mdb-sql and not to the driver lib...Shut
Thank you for that hint, I'll check that ODBTP solution, however I am pretty sure, that it will not be possible to install that service on the Windows machine. It's a closed production system, delivered to our customers by another company. That company gives warranty for that system, but it's void if they modify the environment... By the way - I was sure that there was some magic involved, when I managed to make that ancient mdb-tools work with ODBC :)Shut
S
1

It's been a while...

mdb-tools is CRAP.


We have ended up by writing out own Windows service listening to SQL queries on a port given and proxing them to Access by an ADO connection.

So if only you have such opportunity, I recommend you not to use dead mdb-tools.

Shut answered 12/12, 2014 at 14:33 Comment(2)
Thanks for the update. Sounds like you wound up implementing something quite similar to ODBTP after all....Elisabethelisabethville
That's right. However, our solution is simpler, as it does not require any special PHP-client. The lesson learned is that it appears that there is no easy way to connect to the MS Access database without using some kind of Windows service.Shut
I
0

I have a sneaky suspicion that your WHERE col data contains some special characters like single quotes or double quotes OR there is some issues with PrimaryKey.

I'm using MDBTools and I successfully select cols from tables with wildcards, BUT when i try to select from a certain col that has some double quotes in the data, i get ZERO results. When I run php blah.php on that particular col, I get the error

CRITICAL: can't find column with internal id ### in index PrimaryKey

Found that in the code on line 309, but still not past it... https://github.com/brianb/mdbtools/blob/master/src/libmdb/index.c

Informant answered 24/10, 2017 at 19:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.