我正在尝试从VBA查询数据库,为了避免这样的问题,SQL注入我被告知我应该参数化SQL代码字符串。我目前的代码,没有返回任何错误,但没有结果(!)是:
Sub ImportData_Click()
Dim strSql As String
Dim strDate As String
Dim StrDatetwo As String
Dim strinfo As String
Dim strinfotwo As String
Dim strgroup As String
Dim objConn As ADODB.Connection
Set objConn = New ADODB.Connection
Dim rst As New ADODB.Recordset
Dim ConnectionString As String
'Parameters
strDate = Format(Range("Date"), "DDMMMYY")
StrDatetwo = Format(Range("Datetwo"), "DDMMMYY")
strinfo = "someinfo"
strinfotwo = "total"
strgroup = "total"
'open connection
ConnectionString = "Provider=name ;Data Source=name;Initial Catalog=name;Integrated Security=SSPI"
objConn.Open ConnectionString
'SQL string
strSql = "Declare @mindate date," & _
"@maxdate date " & _
"set @mindate ='" & strDate & _
"'; set @maxdate ='" & StrDatetwo & _
"'; SELECT MIN([results].run_id) " & _
"FROM [results] " & _
"inner join [official_run_table] on ([results].run_id=[official_run_table].run_id and [official_run_table].run_type_id='1' )" & _
" WHERE Info ='" & strinfo & _
"' and two ='" & strinfotwo & _
"' and group= '" & strgroup & _
"' AND [results].date between @mindate and @maxdate"
'MsgBox strSQL '- to check data
rst.Open strSql, objConn
If Not rst.EOF Then
Worksheets("Reference").Range("E2").CopyFromRecordset rst
rst.Close
Else
MsgBox "Error: No records returned.", vbCritical
End If
'Clean up
objConn.Close
Set objConn = Nothing
Set rst = Nothing
End Sub
没有错误但没有结果意味着此查询的数据库中不存在任何值,但我知道其他情况! 我的意图是参数strinfo,strinfotwo,strgroup,但首先我想得到上述工作。我怎么弄错了?提前致谢
答案 0 :(得分:2)
首先,使用?参数化查询字符串?参数标记(用于OLE DB和ODBC驱动程序)而不是字符串文字。注意查询字符串中的参数值不包含在引号中。我将group
列名括在方括号中,因为它是一个保留的SQL关键字,不符合标识符规则。
strSql = "SELECT MIN([results].run_id) " & _
"FROM [results] " & _
"inner join [official_run_table] on ([results].run_id=[official_run_table].run_id and [official_run_table].run_type_id='1' )" & _
" WHERE Info = ?" & _
" AND two = ?" & _
" AND [group] = ?" & _
" AND [results].date between ? and ?;"
下面的示例使用ADODB.Command对象并向查询添加参数。我猜测了您的实际数据类型,因此更改参数类型和长度以匹配您的实际表模式。这是完成此任务的众多方法之一,但应该让您入门。有关更多信息和示例,请参阅ADODB Command reference。
Set parmInfo = command.CreateParameter("@Info", adVarChar, adParamInput, 10, strinfo)
Set parmInfoTwo = command.CreateParameter("@InfoTwo", adVarChar, adParamInput, 10, strinfotwo)
Set parmGroup = command.CreateParameter("@Group", adVarChar, adParamInput, 10, strgroup)
Set parmMinDate = command.CreateParameter("@MinDate", adDBTimeStamp, adParamInput, , strDate)
Set parmMaxDate = command.CreateParameter("@MaxDate", adDBTimeStamp, adParamInput, , strDatetwo)
command.Parameters.Append(parmInfo)
command.Parameters.Append(parmInfoTwo)
command.Parameters.Append(parmGroup)
command.Parameters.Append(parmMinDate)
command.Parameters.Append(parmMaxDate)
Set rst = command.Execute()
答案 1 :(得分:1)
最好的方法是在服务器上构建存储过程,然后传递参数。它绝对是按原样注射的。