Syntax on SQL statement with multiple conditions in WHERE clause - sql

I am getting a run time 3075 issue on the following SQL string below. Is it possible I am missing parentheses?
sql_get =
"SELECT [tblCompetency02].[HighLevelObjective],
[tblCompetency04].[Self],
[tblCompetency04].[SelfSpecialLanguage],
[tblCompetency04].[SelfChecklist],
[tblCompetency04].[Team],
[tblCompetency04].[TeamSpecialLanguage],
[tblCompetency04].[TeamChecklist],
[tblCompetency04].[Organisation],
[tblCompetency04].[OrganisationSpecialLanguage],
[tblCompetency04].[OrganisationChecklist],
[tblCompetency02].[Competency]
FROM [tblCompetency04]
INNER JOIN [tblCompetency02]
ON [tblCompetency04].[HighLevelObjective] = [tblCompetency02].[ID]
WHERE [tblcompetency04].[self]<>"" or [tblcompetency04].[team]<>"" or [tblcompetency04].[organisation]<>"""
Form_frmStaticDataSkills02.Form.RecordSource = sql_get

Examine the WHERE clause of the statement your code creates.
Here's an Immediate window session:
sql_get = "WHERE [tblcompetency04].[self]<>"" or [tblcompetency04].[team]<>"" or [tblcompetency04].[organisation]<>"""
Debug.Print sql_get
WHERE [tblcompetency04].[self]<>" or [tblcompetency04].[team]<>" or [tblcompetency04].[organisation]<>"
Notice there is just one double quote character in each of these cases: <>"
If you want to have double quotes inside the string, use two to get one ...
sql_get = "WHERE [tblcompetency04].[self]<>"""" or [tblcompetency04].[team]<>"""" or [tblcompetency04].[organisation]<>"""""
Debug.Print sql_get
WHERE [tblcompetency04].[self]<>"" or [tblcompetency04].[team]<>"" or [tblcompetency04].[organisation]<>""
But I think it is less confusing and less error-prone to use single quotes inside the string ...
sql_get = "WHERE [tblcompetency04].[self]<>'' or [tblcompetency04].[team]<>'' or [tblcompetency04].[organisation]<>''"
Debug.Print sql_get
WHERE [tblcompetency04].[self]<>'' or [tblcompetency04].[team]<>'' or [tblcompetency04].[organisation]<>''

Related

Passing a string variable in SQL query

I am trying to write a SQL query that takes in WHERE conditional value from a variable.
The variable is a string type and it is being extracted first from a different table using a different query through the use of recordsets. I think I got the quotations right in the query but it shows "Undefined function 'rsDB' in expression" error.
extPMBActID_SQL = "SELECT * FROM PMB;"
Set rsDB = CurrentDb.OpenRecordset(extPMBActID_SQL, dbOpenDynaset)
testID = Left(rsDB.Fields("ActivityID"), 2)
instRptGen_SQL = "SELECT AreaName FROM Area WHERE AreaID =" & "Left(rsDB.Fields('ActivityID'), 2)" & ";"
Set rsDB = CurrentDb.OpenRecordset(instRptGen_SQL, dbOpenDynaset)
I think whenever the query is ran, it is somehow not able to fetch rsDB.Fields("ActivityID") value. I am sure that testID variable does have the value.
Any ideas what I am missing here?
Remove the quotes from that second part:
instRptGen_SQL = "SELECT AreaName FROM Area WHERE AreaID =" & _
Left(rsDB.Fields("ActivityID").Value, 2)
You don't need the terminating ;, and if AreaID is not numeric you need single quotes around the value:
instRptGen_SQL = "SELECT AreaName FROM Area WHERE AreaID ='" & _
Left(rsDB.Fields("ActivityID").Value, 2) & "'"

Syntax error in where clause in Access

The error I am getting is Syntax error in where clause in Access.
Here is the code:
SQL = "Select * FROM tblPermitAgencyInformation & WHERE [RecordID] = " & Me.AgencyInfoRecordID.Value
Set rs = db.OpenRecordset(SQL)
RecordID is an autonumber field and the AgencyInfoRecordID is an integer.
It looks like you misread the article you state. It appears to be attempting to format the adhoc query in the text variable.
Note: it says
strSQL = "SELECT wazzle FROM bamsploot" & vbCrLf & " WHERE plumsnooker = 0"
You need to make sure that you have the ampersands outside of the quotes, (they are used to append variables and strings together in this case)
Follow June7 advice and remove the ampersand there. It should help you get running.
Make your code this:
SQL = "Select * FROM tblPermitAgencyInformation WHERE [RecordID] = " & Me.AgencyInfoRecordID.Value
Hope that helps

Run time error 3075 syntax error on update query

i am having an issue with writing an update query in SQL where there are two clauses one of which has two scenerarios identified with an AND function.
The run time error i am getting is 3075 stating there is syntax errors on the where expression. Loooking at it and after doing a lot of research, i imagine i am almost there.
Thanks, A
st_sql = "UPDATE tblSearchEngine01 SET tblSearchEngine01.Query01OpenItems =""" & _
"WHERE (((tblSearchEngine01.Status)='open')) OR (((tblSearchEngine01.Overall_status) <>'complete') AND ((tblSearchEngine01.Status) Is Null))"
Well, the error is not where you suspect. Two quotes inside a quoted string are interpreted as one quote. You need to double your quotes here :
st_sql = "UPDATE tblSearchEngine01 SET tblSearchEngine01.Query01OpenItems =""""" & _
Consider using single quotes for SQL statements, as this will improve readability.
st_sql = "UPDATE tblSearchEngine01 SET tblSearchEngine01.Query01OpenItems = ''" & _

Ole DB statement runs in Access but not in Visual Studios

I have the following statement and it returns my desired result in Access however in Visual Studio, I receive an error saying "; expected", what could be the problem?
var query = "SELECT Count(*) FROM usersTable WHERE (((usersTable.[uDateCreated]) Between DateAdd("d",-2,Now()) And Now()))";
You need to escape your quotes inside your string:
" .. Between DateAdd(\"d\",-2 .. "
^ ^ escape the quotes
You're using a quotation mark in your query, which is ending the string. Use apostrophes around d instead:
var query = "SELECT Count(*) FROM usersTable WHERE (((usersTable.[uDateCreated]) " & _
"Between DateAdd('d',-2,Now()) And Now()))"
Specifically:
DateAdd('d',-2,Now())
I think your problem is that you have " (quotes) in your string without escaping them. I donut know which language you are using, but for many you escape with \ (backslash), then your string would read DateAdd(\"d\",

Escaping ' in Access SQL

I'm trying to do a domain lookup in vba with something like this:
DLookup("island", "villages", "village = '" & txtVillage & "'")
This works fine until txtVillage is something like Dillon's Bay, when the apostrophe is taken to be a single quote, and I get a run-time error.
I've written a trivial function that escapes single quotes - it replaces "'" with "''". This seems to be something that comes up fairly often, but I can't find any reference to a built-in function that does the same. Have I missed something?
The "Replace" function should do the trick. Based on your code above:
DLookup("island", "villages", "village = '" & Replace(txtVillage, "'", "''") & "'")
It's worse than you think. Think about what would happen if someone entered a value like this, and you haven't escaped anything:
'); DROP TABLE [YourTable]
Not pretty.
The reason there's no built in function to simply escape an apostrophe is because the correct way to handle this is to use query parameters. For an Ole/Access style query you'd set this as your query string:
DLookup("island", "village", "village = ? ")
And then set the parameter separately. I don't know how you go about setting the parameter value from vba, though.
Though the shorthand domain functions such as DLookup are tempting, they have their disadvantages. The equivalent Jet SQL is something like
SELECT FIRST(island)
FROM villages
WHERE village = ?;
If you have more than one matching candidate it will pick the 'first' one, the definition of 'first' is implementation (SQL engine) dependent and undefined for the Jet/ACE engine IIRC. Do you know which one would be first? If you don’t then steer clear of DLookup :)
[For interest, the answer for Jet/ACE will either be the minimum value based on the clusterd index at the time the database file was last compacted or the first (valid time) inserted value if the database has never been compacted. Clustered index is in turn determined by the PRIAMRY KEY if persent otherwise a UNIQUE constraint or index defined on NOT NULL columns, otherwise the first (valid time) inserted row. What if there is more than one UNIQUE constraint or index defined on NOT NULL columns, which one would be used for clustering? I've no idea! I trust you get the idea that 'first' is not easy to determine, even when you know how!]
I've also seen advice from Microsoft to avoid using domain aggregate functions from an optimization point of view:
Information about query performance in an Access database
http://support.microsoft.com/kb/209126
"Avoid using domain aggregate functions, such as the DLookup function... the Jet database engine cannot optimize queries that use domain aggregate functions"
If you choose to re-write using a query you can then take advantage of the PARAMETERS syntax, or you may prefer the Jet 4.0/ACE PROCEDURE syntax e.g. something like
CREATE PROCEDURE GetUniqueIslandName
(
:village_name VARCHAR(60)
)
AS
SELECT V1.island_name
FROM Villages AS V1
WHERE V1.village_name = :village_name
AND EXISTS
(
SELECT V2.village_name
FROM Villages AS V2
WHERE V2.village_name = V1.village_name
GROUP
BY V2.village_name
HAVING COUNT(*) = 1
);
This way you can use the engine's own functionality -- or at least that of its data providers -- to escape all characters (not merely double- and single quotes) as necessary.
But then, it should be like this (with one more doublequote each):
sSQL = "SELECT * FROM tblTranslation WHERE fldEnglish=""" & myString & """;"
Or what I prefer:
Make a function to escape single quotes, because "escaping" with "[]" would not allow these characters in your string...
Public Function fncSQLStr(varStr As Variant) As String
If IsNull(varStr) Then
fncSQLStr = ""
Else
fncSQLStr = Replace(Trim(varStr), "'", "''")
End If
End Function
I use this function for all my SQL-queries, like SELECT, INSERT and UPDATE (and in the WHERE clause as well...)
strSQL = "INSERT INTO tbl" &
" (fld1, fld2)" & _
" VALUES ('" & fncSQLStr(str1) & "', '" & fncSQLStr(Me.tfFld2.Value) & "');"
or
strSQL = "UPDATE tbl" & _
" SET fld1='" & fncSQLStr(str1) & "', fld2='" & fncSQLStr(Me.tfFld2.Value) & "'" & _
" WHERE fld3='" & fncSQLStr(str3) & "';"
I believe access can use Chr$(34) and happily have single quotes/apostrophes inside.
eg
DLookup("island", "villages", "village = " & chr$(34) & nonEscapedString & chr$(34))
Though then you'd have to escape the chr$(34) (")
You can use the Replace function.
Dim escapedString as String
escapedString = Replace(nonescapedString, "'", "''")
Parametrized queries such as Joel Coehoorn suggested are the way to go, instead of doing concatenation in query string. First - avoids certain security risks, second - I am reasonably certain it takes escaping into engine's own hands and you don't have to worry about that.
By the way, here's my EscapeQuotes function
Public Function EscapeQuotes(s As String) As String
If s = "" Then
EscapeQuotes = ""
ElseIf Left(s, 1) = "'" Then
EscapeQuotes = "''" & EscapeQuotes(Mid(s, 2))
Else
EscapeQuotes = Left(s, 1) & EscapeQuotes(Mid(s, 2))
End If
End Function
For who having trouble with single quotation and Replace function, this line may save your day ^o^
Replace(result, "'", "''", , , vbBinaryCompare)
put brackets around the criteria that might have an apostrophe in it.
SOmething like:
DLookup("island", "villages", "village = '[" & txtVillage & "]'")
They might need to be outside the single quotes or just around txtVillage like:
DLookup("island", "villages", "village = '" & [txtVillage] & "'")
But if you find the right combination, it will take care of the apostrophe.
Keith B
My solution is much simpler. Originally, I used this SQL expression to create an ADO recordset:
Dim sSQL as String
sSQL="SELECT * FROM tblTranslation WHERE fldEnglish='" & myString & "';"
When myString had an apostrophe in it, like Int'l Electrics, my program would halt. Using double quotes solved the problem.
sSQL="SELECT * FROM tblTranslation WHERE fldEnglish="" & myString & "";"