Escaping CHR(39) in Query strings (1 Viewer)

ironfelix717

Registered User.
Local time
Today, 01:57
Joined
Sep 20, 2019
Messages
193
Unsurprised, yet again, that escaping quote characters in strings is profoundly difficult.

I am trying to escape the glorious apostrophe, aka chr(39).

Usage:

Code:
Sub test()
Dim Criteria            As String
Dim SQL                 As String

Criteria = "Mc'Hammer"
SQL = "SELECT * FROM POINVrec_Line WHERE MaterialID = '" & Criteria & "';"

Debug.Print SQL
DoCmd.RunSQL SQL  'FAIL......

End Sub


I've made several attempts after reading various threads. None have been successful, as the result is the unlikeable "Syntax error in query expression".

Many have said 'doubling up' the chr(39) is the way to escape.

Code:
If InStr(1, Criteria, Chr(39)) > 0 Then
    Criteria = Replace(Criteria, Chr(39), Chr(39) & Chr(39))
End If
False. Does not work. At least with JET/ACE.


Whats the trick?
Thanks in advance.
 

conception_native_0123

Well-known member
Local time
Today, 00:57
Joined
Mar 13, 2021
Messages
1,834
the error is here:

Code:
MaterialID = '" & Criteria & "';"

you're trying to escape it but your code is adding to it:

Code:
Criteria = Replace(Criteria, Chr(39), Chr(39) & Chr(39))

does this work?

Code:
Criteria = Replace(Criteria, "'", "''")
 

MarkK

bit cruncher
Local time
Yesterday, 22:57
Joined
Mar 17, 2004
Messages
8,181
The best way to deal with delimiters in your data like that is to use a parameter query and a temp QueryDef, like...
Code:
Function GetRSTMcHammer() As DAO.Recordset
    Const SQL As String = _
        "SELECT * FROM YourTable WHERE MaterialID = p0 "
        
    With CurrentDb.CreateQueryDef("", SQL)
        .Parameters("p0") = "Mc'Hammer"
        Set GetRSTMcHammer = .OpenRecordset
    End With
End Function
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 13:57
Joined
May 7, 2009
Messages
19,245
you can also replace it, without using Querydef:
Code:
Sub test()
Dim Criteria            As String
Dim SQL                 As String

Criteria = "Mc'Hammer"
SQL = "SELECT * FROM POINVrec_Line WHERE MaterialID = '" & Replace$(Criteria,"'", "''") & "';"

Debug.Print SQL
DoCmd.RunSQL SQL  'FAIL......

End Sub
 

ironfelix717

Registered User.
Local time
Today, 01:57
Joined
Sep 20, 2019
Messages
193
The best way to deal with delimiters in your data like that is to use a parameter query and a temp QueryDef, like...
Code:
Function GetRSTMcHammer() As DAO.Recordset
    Const SQL As String = _
        "SELECT * FROM YourTable WHERE MaterialID = p0 "
      
    With CurrentDb.CreateQueryDef("", SQL)
        .Parameters("p0") = "Mc'Hammer"
        Set GetRSTMcHammer = .OpenRecordset
    End With
End Function
Thanks for showing a simple example of this. I haven't got into using parameters yet, which from what I understand is the 'proper' way of handling criteria, especially for preventing SQL injection.

However, I need a string-based solution, as that solution has way too much overhead.

you can also replace it, without using Querydef:
Code:
Sub test()
Dim Criteria            As String
Dim SQL                 As String

Criteria = "Mc'Hammer"
SQL = "SELECT * FROM POINVrec_Line WHERE MaterialID = '" & Replace$(Criteria,"'", "''") & "';"

Debug.Print SQL
DoCmd.RunSQL SQL  'FAIL......

End Sub
This somehow works. Can someone explain how
Replace$(Criteria, "'", "''") is any different than Replace(Criteria, Chr(39), Chr(39) & Chr(39))
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 13:57
Joined
May 7, 2009
Messages
19,245
you need to add delimiter to the later:

Replace(Criteria, """" & Chr(39) & """" , """" & Chr(39) & Chr(39) & """")
 

ironfelix717

Registered User.
Local time
Today, 01:57
Joined
Sep 20, 2019
Messages
193
I see whats going on there and its the most un-natural and unintuitive thing I can imagine. Everything I know about strings is now useless.

The following statement should be universally true.

myvar = chr(39)
myvar2 = "'"

"'" = chr(39) = myvar = myvar2


What we've just demonstrated is that the above statement is not true...

Anything enclosed in chr(34) should be interpreted by VBA as LITERAL!

My point: It should not matter whether I am using "'" versus chr(39). As both those statements should be universally equal by VBA.
 

moke123

AWF VIP
Local time
Today, 01:57
Joined
Jan 11, 2013
Messages
3,920
Code:
SQL = "SELECT * FROM POINVrec_Line WHERE MaterialID = '" & Criteria & "';"

Try doubling up the quotes

Code:
SQL = "SELECT * FROM POINVrec_Line WHERE MaterialID = """  & Criteria & """;"

Should work regardless of whether there is a special character or not
 
Last edited:

ironfelix717

Registered User.
Local time
Today, 01:57
Joined
Sep 20, 2019
Messages
193
Code:
SQL = "SELECT * FROM POINVrec_Line WHERE MaterialID = '" & Criteria & "';"

Try doubling up the quotes

Code:
SQL = "SELECT * FROM POINVrec_Line WHERE MaterialID = """  & Criteria & """;"

Hi,

The solution has been provided by @arnelgp

However, I now discovered my original attempt was correct and would work, and I wrongly thought it was flawed due to some incorrect code.

Which also renders my last reply regarding the difference between @arnelgp's solution and mine erroneous.

His solution is the same as my original attemp,t which is why I was extremely confused about them being any different (which they aren't).

Here is an example of a final solution when dealing with chr(39) in SQL strings.
Note that this code will ultimately fail at .RunSQL() because it is a SELECT statement, but will pass in the sense that the query syntax is accepted by DAO.
Code:
Dim sql As String
Dim criteria As String

criteria = "Mc'Hammer"
criteria = Replace(criteria, Chr(39), Chr(39) & Chr(39))
sql = "SELECT * FROM POINVrec_Line WHERE MaterialID = '" & criteria & "';"

Debug.Print sql
DoCmd.RunSQL sql  'PASS!

Alternatively, @arnelgp solution is also acceptable.

Thanks and sorry for the confusion on this petty issue.
Regards
 

ironfelix717

Registered User.
Local time
Today, 01:57
Joined
Sep 20, 2019
Messages
193
Not if Criteria contains a double quote!
Double quotes are not an issue for a SQL string, apparently as I've learned.

If by double quote you mean two instances of chr(34) or even one instance of chr(34).

Code:
criteria = "hello""world"
SQL = "SELECT * FROM MyTable WHERE ID = '" & criteria & "';"

The above will pass all day.

As well as the following:

Code:
criteria = "hello" & Chr(34) & Chr(34) & "world"

Regards
 

cheekybuddha

AWF VIP
Local time
Today, 06:57
Joined
Jul 21, 2014
Messages
2,280
Double quotes are not an issue for a SQL string, apparently as I've learned.
They are if you use a double quote instead of single quote as SQL string delimiter as Moke123 was demonstrating.

The only character you need to escape within an SQL string is the string delimiter. You can use either single quote or double quote - just make sure you escape whichever you choose.
 

ironfelix717

Registered User.
Local time
Today, 01:57
Joined
Sep 20, 2019
Messages
193
The only character you need to escape within an SQL string is the string delimiter.
Not entirely true - See my latest post requesting help on escaping speciality characters in Access SQL.

My most joyous pass-time is figuring out how to escape a 'dot' operator in the string.
 

cheekybuddha

AWF VIP
Local time
Today, 06:57
Joined
Jul 21, 2014
Messages
2,280
Simple test:

1635587991415.png


Code:
Function SQLDblQuoteTest() As Boolean

  Dim SQL As String, Criteria As String
 
  Criteria = "Hello " & Chr(34) & "Moke123" & Chr(34)
  SQL = "SELECT * FROM tblEvents WHERE Narrative = """ & Criteria & """;"
  Debug.Print SQL
  With CurrentDb.OpenRecordset(SQL)
    Do While Not .EOF
      Debug.Print .Fields("Narrative")
      .MoveNext
    Loop
    .Close
  End With
  SQLDblQuoteTest = Err = 0
 
End Function

Immediate Window:
1635588073074.png
 

ironfelix717

Registered User.
Local time
Today, 01:57
Joined
Sep 20, 2019
Messages
193
I did see, but you haven't replied in that thread

Updated with a reply.

I was incorrect again as a result of the original code error.

Special characters (at least the "." character) has no effect on the syntax and works successfully.

Apologies for confusion!

Regards
 

moke123

AWF VIP
Local time
Today, 01:57
Joined
Jan 11, 2013
Messages
3,920
Simple test:

View attachment 95742

Code:
Function SQLDblQuoteTest() As Boolean

  Dim SQL As String, Criteria As String

  Criteria = "Hello " & Chr(34) & "Moke123" & Chr(34)
  SQL = "SELECT * FROM tblEvents WHERE Narrative = """ & Criteria & """;"
  Debug.Print SQL
  With CurrentDb.OpenRecordset(SQL)
    Do While Not .EOF
      Debug.Print .Fields("Narrative")
      .MoveNext
    Loop
    .Close
  End With
  SQLDblQuoteTest = Err = 0

End Function

Immediate Window:
View attachment 95743
I wasn't disagreeing, just 99.9% of the time it's a scenario like the OP's original Criteria = "Mc'Hammer", at least for me.
Should have qualified my statement.
 
Last edited:

Users who are viewing this thread

Top Bottom