我正在尝试使用以下代码在VBA中进行域名查找:
DLookup("island", "villages", "village = '" & txtVillage & "'")
当txtVillage为"Dillon's Bay"这样带有撇号的字符串时,程序会将撇号解释为单引号导致运行时错误。
我写了一个简单的函数来转义单引号——它将"'"替换为"''"。这似乎是一个经常出现的问题,但我找不到任何内置函数来完成相同的功能。我错过了什么吗?
DLookup("island", "villages", "village = '" & Replace(txtVillage, "'", "''") & "'")
情况比你想象的更糟。如果有人输入了这样的值,而您没有转义任何内容,请考虑会发生什么:
'); DROP TABLE [YourTable]
不太美观。
没有内置函数可以简单地转义撇号的原因是正确处理此问题的方法是使用查询参数。对于Ole/Access风格的查询,您应将其设置为查询字符串:
DLookup("island", "village", "village = ? ")
然后单独设置参数。我不知道您如何从vba设置参数值。
SELECT FIRST(island)
FROM villages
WHERE village = ?;
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
);
像Joel Coehoorn建议的那样,参数化查询是正确的方法,而不是在查询字符串中进行连接。首先-避免了某些安全风险,其次-我相当确定它会将转义交给引擎自己处理,您不必担心这个问题。
sSQL = "SELECT * FROM tblTranslation WHERE fldEnglish=""" & myString & """;"
或者我更喜欢的方法是:
制作一个转义单引号的函数,因为使用“[]”进行“转义”不允许在字符串中包含这些字符...
Public Function fncSQLStr(varStr As Variant) As String
If IsNull(varStr) Then
fncSQLStr = ""
Else
fncSQLStr = Replace(Trim(varStr), "'", "''")
End If
End Function
我在所有的SQL查询中使用这个函数,如SELECT、INSERT和UPDATE(以及WHERE子句中...)
strSQL = "INSERT INTO tbl" &
" (fld1, fld2)" & _
" VALUES ('" & fncSQLStr(str1) & "', '" & fncSQLStr(Me.tfFld2.Value) & "');"
或者
strSQL = "UPDATE tbl" & _
" SET fld1='" & fncSQLStr(str1) & "', fld2='" & fncSQLStr(Me.tfFld2.Value) & "'" & _
" WHERE fld3='" & fncSQLStr(str3) & "';"
我相信Access可以使用Chr$(34),并且可以快乐地在其中包含单引号/撇号。
例如
DLookup("island", "villages", "village = " & chr$(34) & nonEscapedString & chr$(34))
虽然这样你就必须转义 chr$(34) (")
你可以使用 Replace 函数。
Dim escapedString as String
escapedString = Replace(nonescapedString, "'", "''")
在可能包含撇号的条件周围加上括号。
类似这样:
DLookup("island", "villages", "village = '[" & txtVillage & "]'")
它们可能需要在单引号外面或者只是在txtVillage周围,比如:
DLookup("island", "villages", "village = '" & [txtVillage] & "'")
但是如果你找到了正确的组合,它会处理撇号。
Keith B
对于那些在单引号和替换函数方面遇到麻烦的人,这行代码可能会让你的一天变得更美好 ^o^
Replace(result, "'", "''", , , vbBinaryCompare)
顺便说一下,这是我的EscapeQuotes函数
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
我的解决方案更简单。最初,我使用了这个SQL表达式来创建一个ADO记录集:
Dim sSQL as String
sSQL="SELECT * FROM tblTranslation WHERE fldEnglish='" & myString & "';"
当myString
中有撇号时,比如Int'l Electrics,我的程序会停止。使用双引号解决了这个问题。
sSQL="SELECT * FROM tblTranslation WHERE fldEnglish="" & myString & "";"