在asp经典中是否可以将参数传递给普通的sql?

时间:2011-08-02 16:01:51

标签: asp-classic sql-injection ado

我见过其他问题......

这可能吗

    SQLStmt.CommandText = "select * from table where id=@id"
     SQLStmt.Parameters.Append SQLStmt.CreateParameter("id", adInteger, _
      adParamReturnValue)
     ' Set value of Param1 of the default collection to 22
     SQLStmt("id") = 22

Set SQLStmt.ActiveConnection = PropConnection
RSProp.Open SQLStmt

2 个答案:

答案 0 :(得分:1)

方法I've recommended before是声明变量并将它们绑定到参数,然后引用实际SQL语句中的变量。

DECLARE @id = ?;
select * from table where id=@id

您仍然需要按位置绑定参数,但是您可以在SQL语句中继续使用命名变量,而且如果您多次使用同一个变量,则只需将其绑定一次。

答案 1 :(得分:0)

答案是。像往常一样愚蠢的老派VB和asp充满洞,故障和无意义。

所以我掀起了这个小类作为包装器并允许我传递带有@prefixed变量名的简单字符串并生成非命名参数sql以发送回sql server。

这可能看起来很愚蠢,但对我来说,能够明确地编写我的sql语句,例如Select field1,field2,field3 from table where field1 =@field1 and field2 = @field2对我来说非常有价值。我已经在底部包含了一个使用此代码的示例。

也许我为自己提供了一种虚假的安全感,但在我看来,我不仅通过使用参数化查询来阻止sql注入攻击,我还添加了另一级别的锁定,因为我已经设置了sql字符串作为常数。

Class SQLBuilder

Private Sub Class_Initialize(  )
    Set internal_commandObject = Server.CreateObject("ADODB.Command")
End Sub

Private internal_sql
Private internal_parameters
private internal_commandObject

Public Property Let CommandType(ByVal value)
    internal_commandObject.CommandType = value
End Property

Public Property Get CommandType
    CommandType = internal_commandObject.CommandType
End Property

Public Property Let Prepared(ByVal value)
    internal_commandObject.Prepared = value
End Property

Public Property Get Prepared
    Prepared = internal_commandObject.Prepared
End Property

Public Property Get SQLCommandObject
Set SQLCommandObject = internal_commandObject
End Property

Public Property Let SQLCommandObject(ByVal value)
Set internal_commandObject = value
End Property

Public Property Get CommandText
    CommandText = internal_commandObject.CommandText
End Property

Public Property Let CommandText(ByVal sqlStatement)
    GetSQLParameters sqlStatement
    internal_commandObject.CommandText =  internal_sql
End Property

Public Property Get Parameters
    Set Parameters = internal_parameters
End Property

Private matches

Public Function SetParameter(name,datatype,direction,size,value)
 internal_commandObject.Parameters.Append internal_commandObject.CreateParameter(name,datatype,direction,size,value)
End Function 

Private Sub GetSQLParameters(sql)

    Set RegExObj = New RegExp

    With RegExObj
        .Global = true
        .Multiline = true
        .Pattern = "@\S+"
        .IgnoreCase = true
    End With

    Set internal_parameters =  CreateObject("Scripting.Dictionary")

    set matches = RegExObj.Execute(sql)

    With internal_parameters
        For each item in matches
        if Not .Exists(item.value) then  
            .Add item.value,item.value
        end if
        Next

    End With
    internal_sql = RegExObj.Replace(sql,"?")
End Sub
End Class

Public Const GET_PROPERTY_INFO = "select AccountNumber, ParcelID, UserAccount, LocationLookup, StreetNumber, Unit, OwnerLookup, LUC, NBC, isnull(TotalLand,0) as TotalLand, UpdtDate from STAGE.DataProperty where FISCAL_YEAR = @FISCAL_YEAR AND AccountNumber = @ACCOUNT_NUMBER"
Dim Temp
Dim mySqlBuilder
set mySqlBuilder = new SQLBuilder

With mySqlBuilder
    set .SQLCommandObject.ActiveConnection = PropConnection
    .CommandType = adCmdText
    .CommandText = GET_PROPERTY_INFO
    .Prepared = true
    .SetParameter "@FISCAL_YEAR",adInteger,adParamInput,4,Cint(Year)
    .SetParameter "@ACCOUNT_NUMBER",adVarChar,adParamInput,13,AccountNumber
End With

    RSProp.Open mySqlBuilder.SQLCommandObject