- Syntax error (missing operator) in query expression 'field='some_partial_string'
- Syntax error in INSERT INTO statement
- Syntax error in UPDATE statement
- Syntax error in FROM clause
- Syntax error in WHERE clause
There are 4 main causes for these errors: using a Reserved Word for a field name; embedded spaces in field or table names; attempting to insert unescaped single quotes; and incorrectly delimited datatypes. There is a fifth cause, and that is a genuine syntax error resulting from a typo, or otherwise misconstructed SQL statement. Assuming that you are sure this fifth cause is not applicable in your case, here's how to deal with the other four.
Reserved Words and Embedded Spaces
The most common culprits among reserved words are NAME and PASSWORD, which at first glance appear to be perfectly reasonable choices for field names in, say, a User table. What can be more confounding is that PASSWORD doesn't appear on this list of reserved words in Access. However, the fact is that in an ASP.NET application, you aren't dealing with an Access database. It's actually a Jet 4.0 database, and there is a separate list of reserved words for Jet 4.0 that does indeed include PASSWORD (but not NAME). Best advice is to familiarise yourself with both lists (and the one for Sql Server Reserved Words too) and avoid using any of them as a habit. However, if you can't change your field names, you will have to srround them with [ ] brackets:
Select [name], [password], emailaddress From Users
The same resolution applies to embedded spaces in field names: change them or surround them in [ ] brackets:
Select [user name], userpassword, [email address] From Users
When using the Query Builder within Visual Studio or Visual Web Developer, you will find that all field names are surrounded by brackets by default.
Unescaped Single Quotes and Incorrect Datatype Delimiters
The third and fourth causes of these errors will be totally resolved if you use parameters in your code. Single quotes act as string delimiters in Jet SQL, so when you try to pass a vlaue that contains a quote, such as a name like O'Brien, or a piece of text like "It's a lovely day", the Jet engine baulks and throws an error. It thinks that the apostrophe or single quote is telling it that the string value to be passed has ended, and anything afterwards should be treated as legitimate SQL.
In the same way that single quotes delimit string values, other datatypes also have their own delimiters:
text/string | single quote | ' |
numeric | none | |
datetime | single quote or octothorpe | ' or # |
If you get these wrong, a Syntax error will be thrown. Paramterised queries solve the problem, because the Jet engine infers the datatype from the database field, and treats the value being passed in the correct way. This means that things like "O'Brien" are treated as literal strings. You will see advice from some people recommending that you use some form of string.Replace() method to double any single quotes, which works by escaping them. While this works, it's a poor idea.