Как отфильтровать данные, проанализированные из базы данных, используя ASP - PullRequest
0 голосов
/ 07 октября 2019

Я недавно получил в свои руки проект ASP, который был довольно беспорядочным. Я не знаком с языком, но, потратив некоторое время на поиск в Интернете, мне удалось выучить его, но я все еще незнаком с запросами к базе данных и т. Д.

Так вот в чем проблема, у меня естьэтот код, который получает данные из файла базы данных MS Access. Я хочу отфильтровать эти данные на основе переданных параметров post / get.

Вот код, который у меня есть:

sql = "SELECT * FROM tyres"

if len(brand1) > 2 then 
     sql = sql & " WHERE brand = '" & brand1 & "' AND application = '" & season1 & "'"

if len(brand2) > 2 then 
     sql = sql & " or brand = '" & brand2 & "' AND application = '" & season2 & "'"

if len(brand3) > 2 then 
    sql = sql & " or brand = '" & brand3 & "' AND application = '" & season3 & "'"

if len(brand4) > 2 then 
    sql = sql & " or brand = '" & brand4 & "' AND application = '" & season4 & "'"

if len(brand5) > 2 then 
    sql = sql & " or brand = '" & brand5 & "' AND application = '" & season5 & "'"

set Dataconn = Server.CreateObject("ADODB.Connection") 
Dataconn.Open "database-in"
set DataTable = Server.CreateObject("ADODB.recordset")
DataTable.Open sql, Dataconn

И, похоже, он не работает. Обратите внимание, что пользователь может вставить до 5 (как вы можете видеть) различных параметров для поиска товаров в БД. Так что если у вас есть дополнительная информация о том, как сделать эту работу, не стесняйтесь предлагать.

Ответы [ 2 ]

1 голос
/ 07 октября 2019

Весьма неразумно создавать SQL из конкатенации строк, и даже правый опасен , если эти строки частично получены из пользовательского ввода.

Библиотеки баз данных, такие как ADODB, имеют команды и параметры для этой ситуации. Они используют фиксированную строку SQL с заполнителями, а библиотека гарантирует, что ничего плохого не произойдет, независимо от того, какие значения могут быть предоставлены пользователем.

Это также означает, что мы можем подготовить оператор SQL заранее и повторно-использовать его много раз за время существования страницы.

Dim Conn ' As ADODB.Connection
Dim Cmd  ' As ADODB.Command

Set Conn = Server.CreateObject("ADODB.Connection")
Set Cmd = Server.CreateObject("ADODB.Command")

Conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\path\to\your\database.accdb;"

' prepare a reusable command with parameters (i.e. placeholders)
With Cmd
  Set .ActiveConnection = Conn
  .CommandType = adCmdText
  .CommandText = "SELECT Field1, Field2, Field3 WHERE brand = @brand AND application = @season"

  ' set up the parameters for each placeholder
  '  - use proper datatypes here, as per your DB
  '  - varchar types need a defined length
  .Parameters.Append .CreateParameter("@brand", adVarChar, , 50)
  .Parameters.Append .CreateParameter("@season", adVarChar, , 100)
End With

' helper function that operates the Command object and returns a RecordSet
Function SearchTyres(brand, season)
  Cmd.Parameters("@brand", brand)
  Cmd.Parameters("@season", season)
  Set SearchTyres = Cmd.Execute
End With

Удобно иметь возможность использовать в своем коде специфичные для ADODB константы, такие как adCmdText или adVarChar. Чтобы они были доступны в любом месте без суеты, вам нужно объявить библиотеку типов ADODB в файле global.asa (создайте ее, если у вас ее нет), добавив ее в начало файла:

<!--metadata 
    type="TypeLib" 
    name="Microsoft ActiveX Data Objects 6.1 Library" 
    uuid="B691E011-1797-432E-907A-4D8C69339129"
    version="6.1"
-->

Теперь вы можете использовать это на своей странице, например:

If Len(brand1) > 2 Then
  With SearchTyres(brand1, season1)
    ' ...let's do something with the RecordSet
    While Not .EOF
      Response.Write Server.HTMLEncode(!Field1) & "<br>"
      .MoveNext
    Wend
  End With
End If

Заметки

  • Не делайте SELECT * - всегда записывайте поля, которые вы хотите иметь.
  • Объявление библиотеки типов не является строго обязательным, но если вы этого не сделаете, то вам нужно определить все константы, например, adVarChar, и это намного сложнее, чем стоит.
  • With SearchTyres(...) - сокращенное обозначение удобства для

    Dim Rs
    Set Rs = SearchTyres(...)
    With Rs
      ' ...
    End With
    
  • Rs!Field1 - сокращенное обозначение удобства для Rs.Fields("Field1"). Внутри блока With Rs сам Rs является необязательным, поэтому значение !Field1 действительно имеет смысл.

  • Наконец, это может помочь в создании кода в VBA IDE MS Office. продукт (такой как Word). Используйте Инструменты / Ссылки для ссылки на ту же библиотеку типов ADODB. VBA и VBS не совместимы на 100 кодов, но IDE VBA имеет Intellisense, правильный отладчик, использует те же объекты, и код может быть перенесен в ASP с минимальными изменениями.
0 голосов
/ 09 октября 2019

Поскольку все остальные заняты избиением вас, вместо того, чтобы фактически ответить на ваш вопрос о том, как построить вашу строку sql:

<%

    SqlStr = "SELECT * FROM Tyres WHERE 1 = 1 " 
    If Len(brand1) > 2 OR  Len(brand2) > 2 OR  Len(brand3) > 2 OR  Len(brand4) > 2 OR  Len(brand5) > 2 Then
        BrandInStr = " AND brand IN("
            If Len(brand1) > 2 Then
                BrandInStr = BrandInStr & "'" & brand1 & "',"    
            End If          
            If Len(brand2) > 2 Then
                BrandInStr = BrandInStr & "'" & brand2 & "',"    
            End If              
            If Len(brand3) > 2 Then
                BrandInStr = BrandInStr & "'" & brand3 & "',"    
            End If              
            If Len(brand4) > 2 Then
                BrandInStr = BrandInStr & "'" & brand4 & "',"    
            End If                  
            If Len(brand5) > 2 Then
                BrandInStr = BrandInStr & "'" & brand5 & "',"    
            End If  
        BrandInStr = Left(BrandInStr,Len(BrandInStr)-1)             
        BrandInStr = BrandInStr & ") "
    End If
    If Len(season1) > 2 OR  Len(season2) > 2 OR  Len(season3) > 2 OR  Len(season4) > 2 OR  Len(season5) > 2 Then
        SeasonInStr = " AND Season IN("
            If Len(Season1) > 2 Then
                SeasonInStr = SeasonInStr & "'" & Season1 & "',"    
            End If          
            If Len(Season2) > 2 Then
                SeasonInStr = SeasonInStr & "'" & Season2 & "',"    
            End If              
            If Len(Season3) > 2 Then
                SeasonInStr = SeasonInStr & "'" & Season3 & "',"    
            End If              
            If Len(Season4) > 2 Then
                SeasonInStr = SeasonInStr & "'" & Season4 & "',"    
            End If      
            If Len(Season5) > 2 Then
                SeasonInStr = SeasonInStr & "'" & Season5 & "',"  
            End If  
        SeasonInStr = Left(SeasonInStr,Len(SeasonInStr)-1)              
        SeasonInStr = SeasonInStr & ") "
    End If

    SqlStr = SqlStr & BrandInStr & " " & SeasonInStr

%>

Однако, если ваши переменные передаются как одна строка, разделенная запятыми (вместо нумерации)было бы намного проще

<%

    SqlStr = "SELECT * FROM Tyres WHERE 1 = 1 "

    If Len(Trim(Replace(Replace(Brand," ",""),",","") > 0 Then
       SqlStr = SqlStr & "AND Brand In('" & Replace(Brand,",","','") & "') "
    End If


    If Len(Trim(Replace(Replace(Season," ",""),",","") > 0 Then
       SqlStr = SqlStr & "AND Season In('" & Replace(Season,",","','") & "') "
    End If

%>
...