im using MS Access as DB and the Field im searching is a Short Text. would like to know how i could search a field and match it with wildcards. For example('x' is wildcard) -
x0x6 (matches 1016, 1076.....)
x06x (matches 9067, 3068....)
.
.
.
have search online and found sample using this - % ? #, but none works for me :/
here is my sql query -
SELECT COUNT(DPlace) as CounTotal
FROM tblTest2
WHERE DSide=1 AND
DNumber LIKE '%06%' AND DDate BETWEEN #09-13-16# AND #09-13-17#
SELECT COUNT(DPlace) as CounTotal
FROM tblTest2
WHERE DSide=1 AND
DNumber LIKE '%0%6' AND DDate BETWEEN #09-13-16# AND #09-13-17#
Both the sql above returns wrong result as they matches all field that has '06'. Please advice. Thank you.
Here is an explanation of why [0-9] works and ? and # does not in your LIKE pattern. TL;DR - You are using the Access backend which runs ANSI-92 mode.
Background
MS Access is a unique type of software in that it is two-fold:
FRONT-END: A GUI .exe program and part of the MS Office Suite (with Word/Excel/PowerPoint) only for Windows installs. This GUI program can serve as a "front-end" to connect to any ODBC/OLEDB compliant "back-end" RDBMS database such as SQL Server, Postgres, MySQL, SQLite, etc.
BACK-END: By default, Access GUI connects to the Windows' JET/ACE SQL Engine (Windows .dll files), a file-system data store, which over time has been considered the "Access database" but any Windows program or script can connect to it without MSAccess.exe installed. Likewise, any application layer language (VB, C#, PHP, Python, Java) with appropriate ODBC/OLEDB libraries can connect to this backend. In fact, when using the GUI, VBA is connected by default! So really Access is a GUI console to database (#1 definition).
OP as commented is using VB6 (application code) to connect to the JET/ACE engine as a backend database, no where using the GUI program.
LIKE Operator
The above dichotomy is particularly relevant concerning the LIKE operator:
Using the GUI version of Access, its SQL dialect tends to be ANSI-plus and can interface with VBA. Hence, the LIKE operator behaves very similar to VBA's LIKE operator. Also, the LIKE operator runs in ANSI-89 mode which uses the asterisk * and not % wildcard for LIKE as well as ? and #. Even so, the GUI's LIKE can use percentage symbol with the ALIKE operator or setting the database to ANSI-92 mode (and not the default ANSI-89).
Using the backend database of Access as OP does, the SQL dialect uses ANSI-92 mode which MS docs show include:
%: Matches any number of characters. It can be used as the first or last character in the character string.
_: Matches any single character within the brackets.
[]: Matches any single alphabetic character.
-: Matches any one of a range of characters. You must specify the range in ascending order (A to Z, not Z to A).
Notice unlike the ANSI-89 mode, the symbols ? and # are not included. But the last symbol, the hyphen, matches a range of characters such as digits, [0-9]. The same below SQL statement if run inside the MSAccess.exe will not return same results unless you run in ANSI-92 mode.
SELECT COUNT(DPlace) as CountTotal
FROM tblTest2
WHERE DSide=1
AND DNumber LIKE '[0-9]0[0-9]6'
AND DDate BETWEEN #09-13-16# AND #09-13-17#
MS Access uses different like patterns from other databases. These are well-documented.
From what you describe, you want either:
DNumber LIKE '?06?'
where ? can be any character.
or:
DNumber LIKE '#06#'
where # is specifically a digit.
You can also write the latter as:
DNumber LIKE '[0-9]06[0-9]'
and this will work in SQL Server as well.
In any other database, the placeholder for any character is _:
DNumber LIKE '_06_'
This does not have the same effect in MS Access.
In Access it will be:
SELECT
COUNT(*) as CounTotal
FROM
tblTest2
WHERE
DSide=1 AND DNumber LIKE '?0?6' AND DDate BETWEEN #09-13-16# AND #09-13-17#
Related
I hope someone can shed some light on this strange behavior.
I have a very simple sql statement thus:
"SELECT TOP 1 PartRefID FROM Parts WHERE PartDescription LIKE '*Backshell*' AND ParentID = 2097"
which is executed scalar.
when I enter this in the access query editor it works just fine and returns the expected value.
however, when I run it from within some vb.net code it always returns zero.
can anyone tell me why this is the case?
thanks
When using .net, you have to use the % sign - it more of a ANSI standard, and this works with jet/ace (access) data engine also.
So, when writing .net code as opposed to VBA, then you are to use % for wild cards - not *. In fact, even in Access VBA, if you were to use ADO (as opposed to the more common and recommended DAO - then even in VBA + ADO, you have to use % in place of *).
so in fact most sql syntax uses %. For ADO, or now what is called ado.net? Then % is to be used.
However, inside access? You can turn on ANSI compatibility - but it WILL make a huge mess of existing access applications - so I don't recommend doing this (enabling Access ANSI sql compatibility mode).
You can quite much assume for "most" software outside of Access - EVEN when hitting the Access database, you use % for wild cards. The only exception here is if one was to use DAO directly as a reference library, and I STRONG recommend you don't do this.
so try using % - and all should be find and well.
Try to replace *
"SELECT TOP 1 PartRefID FROM Parts WHERE PartDescription LIKE '%Backshell%' AND ParentID = 2097"
I have a subject table which has a theme field contains the following rows :
theme
-----
pays
économie
associée
And I have this basic query :
SELECT * FROM SUBJECT WHERE THEME='associée';
The query runs fine in Sql developer and returns the expected row to me.
On the other hand under Sqlplus it returns 0 lines to me (which is not normal).
I have the impression that the query does not recognize accented characters under sqlplus. I am thinking of an NLS_LANG problem but I do not know about it. Please help.
Thank you in advance.
Set your OS session's NLS_LANG variable to the value of, e.g., ENGLISH_AMERICA.AL32UTF8 and restart your SQL Developer. Retry afterwards.
If that didn't help, try also running your query as follows:
SELECT * FROM SUBJECT WHERE THEME = n'associée';
Notice the n before the string literal. That's a nvarchar2 string literal modifier. Depending on your DB charset/national charset settings you may need to explicitly state that the value you are querying for, is "national charset", not just a "regular charset".
If that didn't help, there's actually a multitude of additional variables that come into play when working with accented characters against an Oracle DB.
Explanation:
Your SQL Developer does recognize accents... provided that you have your Oracle DB session using character set compatible with your database character set. And your Oracle DB session's character set can be set either on OS level (via OS environment variable) or, possibly(!), in SQL Developer's options directly. Alas, the said multitude of other factors may include (though not exclusively):
your OS regional settings,
your OS Unicode support,
your Oracle client software's (SQL Developer) Unicode support,
your Java JDK/JRE's Unicode support,
your JDBC driver's Unicode support,
your other *DBC drivers' Unicode support, if there are any more in chain.
Sad thing is that the more interfaces you have between your keyboard and your Oracle database, the more likely is one of them to fiddle with your charset conversions badly.
So, let's just hope that the first two hints work for you, otherwise I can't help you (that easily).
I'm adding a table to my database - CREATE TABLE dbo.Card - and SSMS is highlighting the word Card. I'm searching the internet trying to find out what that word means to SQL and if it is a keyword or not. I don't see it anywhere on Microsoft's list of SQL Reserved Words.
The main reason I care, aside from the highlighting bothering me, is that I want to avoid using any reserved words or keywords as schema/table/column/etc... names. When I absolutely have to - existing databases - I like to use square brackets to make things explicit.
Is Card a reserved word or keyword in SQL, or for any other reason unsafe to use as an identifier?
If it is safe to use, can anyone explain why SSMS is highlighting it?
If it is not 100% safe to use as a table name I'll most likely choose a different name.
Windows 8.1
SSMS v17.7
Red Gate - Up to date, including SQL Prompt 9.4.9
SQL Server 2017 (14.0)
Database Compatibility Level 2017 (140)
UPDATE
It looks like the main consensus is:
It is not a reserved or keyword
SSMS highlights it because reasons... It's probably used somewhere by MS SQL Server or SSMS
At this point I'm just terribly curious, but at least I know there's no need to worry. Thanks everyone for your answers.
No, card is not a reversed word in Microsoft SQLServer or SQL ANSI standard.
Card is definitely not a reserved keyword in SQL Server
You can check the complete list of reserved words Reserved Keywords (Transact-SQL)
SSMS highlights it because reasons... It's probably used somewhere by
MS SQL Server or SSMS
They are various keywords that have been subjectively chosen by Microsoft and placed into a list within the query editor syntax coloring file.
I suggest it's always good to use Delimited Identifiers ([] or ") when specifying table name and column names.
For example, the script you are using should be written as
CREATE TABLE [dbo].[Card](<Columns>)
I'm attempting to run a simple statement against an Access DB to find records.
Data validation in the records was horrible, and I cannot sanitize it. Meaning, it must be preserved as is.
I need to be able to search against a string with white space and hyphen characters removed. The following statement will work in Access 2010 direct:
select * from dummy where Replace(Replace([data1],' ',''),'-','') = 'ABCD1234';
Running it from an ODBC connection via PHP will not. It produces the following error:
SQL error: [Microsoft][ODBC Microsoft Access Driver] Undefined function 'Replace' in expression., SQL state 37000 in SQLExecDirect
Creating a query in the database that runs the function and attempting to search its values indirectly causes the same error:
select * from dummy_indirect where Expr1 = 'ABCD1234';
I've attempted to use both ODBC drivers present. ODBCJR32.dll (03/22/2010) and ACEODBC.dll (02/18/2007). To my knowledge these should be current as it was installed with the full Access 2010 and Access 2010 Database Engine.
Any ideas on how to work around this error and achieve the same effect are welcome. Please note, that I cannot alter the database in way, shape, or form. That indirect query was created in another mdb file that has the original tables linked from the original DB.
* Update *
OleDB did not really affect anything.
$dsn= "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\dummy.mdb;";
I'm not attempting to use it as a web backend either. I'm not a sadomasochist.
There is a legacy system that I must support that does use Access as a backend. Data gets populated there from other old systems that I must integrate into more modern systems. Hence, the creation of an API with Apache/PHP that is running on the server supporting the legacy system.
I need to be able to search a table that has an alphanumeric case identifier to get a numeric identifier that is unique and tied to a generator (Autonumber in access). Users have been using it a trash box for years (inconsistent data entry with sporadic notations) so the only solution I have is to strip everything except alphanumeric out of both the field value and the search value and attempt to perform a LIKE comparison against it.
If not replace() which is access supported, what ODBC compatible functions exist that I can use do the same kind of comparison?
Just to recap, the Access db engine will not recognize the Replace() function unless your query is run from within an Access application session. Any attempt from outside Access will trigger that "Undefined function" error message. You can't avoid the error by switching from ODBC to OleDb as the connection method. And you also can't trick the engine into using Replace() by hiding it in separate query (in the same or another Access db) and using that query as the data source for your main query.
This behavior is determined by Access' sandbox mode. That linked page includes a list of functions which are available in the default sandbox mode. That page also describes how you can alter the sandbox mode. If you absolutely must have Replace() available for your query, perhaps the lowest setting (0) would allow it. However, I'm not recommending you do that. I've never done it myself, so don't know anything about the consequences.
As for alternatives for Replace(), it would help to know about the variability in the values you're searching. If the space or dash characters appear in only one or a few consistent positions, you could do a pattern match with a Like expression. For example, if the search field values consist of 4 letters, an optional space or dash, followed by 4 digits, a WHERE clause like this should work for the variations of "ABCD1234":
SELECT * FROM dummy
WHERE
data1 = 'ABCD1234'
OR data1 Like 'ABCD[- ]1234';
Another possibility is to compare against a list of values:
SELECT * FROM dummy
WHERE
data1 IN ('ABCD1234','ABCD 1234','ABCD-1234');
However if your search field values can include any number of spaces or dashes at any position within the string, that approach is no good. And I would look real hard for some way to make the query task easier:
You can't clean the stored values because you're prohibited from altering the original Access db in any way. Perhaps you could create a new Access db, import the data, and clean that instead.
Set up the original Access db as a linked server in SQL Server and build your query to take advantage of SQL Server features.
Surrender. :-( Pull in a larger data set to your PHP client code, and evaluate which rows to use vs. which to ignore.
I'm not sure you can do this with ODBC and your constraints. The MS Access driver is limited (by design; MS wants you to use SQL Server for back ends).
Can you use OLEDB? that might be an option.
I have a simple query but am running into problems using LIKE in VBA. My SQL string in VBA is:
stsql1 = "Select Top 25 data.* from data where data.Description Like ('*') "
When I run this sql string in my VBA code I get no records returned, but if I copy/paste the same string into a query in SQL View in MS Access, the query returns the values I expect. Is there a trick to using the "Like" syntax in VBA?
I can provide additional code and a small version of the database if that would help.
For SQL, the database engine will accept either single or double quotes as text delimiters. So either of these 2 WHERE clauses will work.
WHERE some_field Like '*'
WHERE some_field Like "*"
VBA however only accepts double quotes as text delimiters, so you would have to use the second form.
Two other points about your SELECT statement:
Select Top 25 data.* from data where data.Description Like ('*')
TOP [number] is arbitrary without an ORDER BY clause
You don't need parentheses surrounding your Like pattern ... you can use Like "*"
If your VBA code is using ADO with that SELECT statement, you must change the wild card character from * to % ...
WHERE data.Description Like '%'
In ADO/VBA, you have to use % instead of * as the wildcard. I ran into this a couple times in the past ....
Realize that there are at least 2 (yes two!) LIKE operators here.
One is the LIKE operator of VBA.
The other is the LIKE operator of the SQL of the database you are attached to.
The usual wildcards in SQL are % (for any # of any characters) and _ (for one of any character).
Know also that MS Access can open databases that aren't Access; it could be Microsoft SQL Server, or Oracle or IBM DB2. (BTW, the database that is normal for Access is called Microsoft JET.) You may be sheltered from that truth when you create a Query object in Access - in that circumstance, you are using JET SQL even when it's a linked table you are querying.
However, under VBA, when using either DAO or ADO, you're talking directly to whatever the database system happens to be, in which case you MUST use the SQL of that specific system.
OK, short answer: Use % like cularis said.
I can't add a comment, but I think it would be worth noting that you have to use % even if you are querying MS Access.
(example: Outlook VBA runs query on an Access database. The proper query is select * where user like '%bob%', even though this query would not work if plugged directly into an MS Access query).