我已声明了存储SQL表中列名称的变量以及存储其相应“要查找的值”的变量。
Dim sColumn1 As String
Dim sColumn2 As String
Dim sColumn3 As String
Dim sValue1 As String
Dim sValue2 As String
Dim sValue3 As String
sColumn1 = Sheets(1).Range("A1").Value
sColumn2 = Sheets(1).Range("B1").Value
sColumn3 = Sheets(1).Range("C1").Value
sValue1 = Sheets(1).Range("A2").Value
sValue2 = Sheets(1).Range("B2").Value
sValue3 = Sheets(1).Range("C2").Value
我想做一个像这样的动态查询:
StrQuery = "SELECT * FROM dbo.Table1 WHERE ('" & sColumn1 & "') LIKE ('" & sValue1 & "') AND ('" & sColumn2 & "') LIKE ('" & sValue2 & "') AND ('" & sColumn3 & "') LIKE ('" & sValue3 & "')"
此代码不会产生任何错误,但IT也不会提取任何记录。我已经确认并且所有变量都被赋予了正确的值。
如果我替换SQL表中实际列名的Column变量,上面的查询工作正常。像这样:
StrQuery = "SELECT * FROM dbo.Table1 WHERE Column1 LIKE ('" & sValue & "') AND Column2 LIKE ('" & sValue2 & "') AND Column3 LIKE ('" & sValue3 & "')"
使用此字符串,我得到的结果没有任何问题,但列将是动态的。用户将从各种15列中进行选择。
为什么当我使用变量时,即使我知道变量的值与SQL表中的列的名称完全匹配,它也不起作用?
我在字符串中使用了错误的格式,以便它读取存储在变量中的实际值吗?
关于使用参数化查询的上述警告仍然适用,但这是您如何使其工作:
StrQuery = "SELECT * FROM dbo.Table1 WHERE " & _
sColumn1 & " LIKE ('%" & sValue & "%')" & _
" AND " & sColumn2 & " LIKE ('%" & sValue2 & "%')" & _
" AND " & sColumn3 & " LIKE ('%" & sValue3 & "%')"
如果输入有效,@ TimWilliams的答案应该解决没有得到任何结果的问题。但是,正如评论中所述,代码有点脆弱,因为在表单的字段中输入格式错误或不适当的值可能会产生有趣的结果。所以,我想建议一种比简单执行SQL字符串更强大的方法。
如果您使用ADO与SQL Server通信,则可以按照this SO answer中的说明调用存储过程。此外,如果您至少在SQL Server 2008上,则存在过程sp_executesql。此存储过程允许您执行包含参数的SQL字符串。第一个参数是SQL字符串,第二个参数是包含参数列表的字符串,以下参数是查询的实际参数。这允许您将表示LIKE模式的字符串作为实际字符串参数传递。因此,无论值是什么,它们都无法破坏查询本身。
关于列名,您至少应使用方括号对它们进行转义。这不是防水的,但对于意外畸形的价值观已经走了很长的路。
结果就像是
sqlString = "SELECT * FROM dbo.Table1 " & _
"WHERE [" & sColumn1 & "] LIKE @value1 " & _
" AND [" & sColumn2 & "] LIKE @value2 " & _
" AND [" & sColumn3 & "] LIKE @value3 "
parameterDeclarationString = "@value1 AS NVARCHAR(1000)," & _
"@value2 AS NVARCHAR(1000)," & _
"@value3 AS NVARCHAR(1000)"
请注意,参数的最大长度只是合理上限的任意猜测。