Использование значения VBA Combobox в SQL Query, возвращающего несоответствие типов - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть пользовательская форма, которая содержит список агентов. Когда вы нажимаете на агента и нажимаете кнопку, чтобы пометить его как не находящегося здесь, появляется всплывающее окно, которое требует, чтобы вы выбрали причину, которой их здесь нет.

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

При запуске я получаю несоответствие типов в строке .additem rs![Five9 Extension]. Столбец в таблице SQL - varchar, и мне просто нужно, чтобы он отображал число, поэтому я не совсем уверен, в чем проблема.

Dim Cn As ADODB.Connection
Dim Server_Name As String
Dim Database_Name As String
Dim SQLStr As String
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset

Server_Name = "SDL02-VM25"
Database_Name = "PIA"
SQLStr = "select [Five9 Extension] from dbo.[Master Staffing List] Where [Agent Name] ='" & MainPage.AgentName.Selected(itemIndex) & "'"

Set Cn = New ADODB.Connection
Cn.Open "Driver={SQL Server};Server=" & Server_Name & ";Database=" & Database_Name & ""
rs.Open SQLStr, Cn, adOpenStatic

With ReasonPopup.CurPoints
    .Clear
    Do
        .AddItem rs![Five9 Extension]
        rst.MoveNext
    Loop Until rst.EOF
End With

rs.Close
Cn.Close
Set rs = Nothing
Set Cn = Nothing
Exit Sub

1 Ответ

0 голосов
/ 27 апреля 2018

Оператор Bang неявных вызовов членов по умолчанию в стороне (rs![Field Name] является сокращением для rs.Fields("Field Name").Value), кажется, что запрос не возвращает то, что, как вы думаете, он делает:

SQLStr = "select [Five9 Extension] from dbo.[Master Staffing List] Where [Agent Name] ='" & MainPage.AgentName.Selected(itemIndex) & "'"

ListBox.Selected(index) возвращает Boolean, поэтому отправляемый вами запрос выглядит примерно так:

select [Five9 Extension] from dbo.[Master Staffing List] Where [Agent Name] ='True'

.... Что, как я ожидаю, даст в итоге 0 строк.

Вопрос: что произойдет, если [Agent Name] будет Jake O'Neil? Правильно, синтаксическая ошибка с запросом. А что если [Agent Name] будет Robert'; DROP TABLE [Master Staffing List];--? Правильно, очень плохие вещи . Это называется уязвимость SQL-инъекций , и она преследует код запросов к базе данных по всему миру, когда люди объединяют предложения WHERE с пользовательскими данными. Это не только вопрос безопасности базы данных, но и причина легко устраняемых ошибок.

Давайте исправим это. Используйте ADODB.Command, и в строке SQL удалите одинарные кавычки и замените конкатенацию параметров знаком вопроса:

Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = Cn
cmd.CommandText = "SELECT [Five9 Extension] FROM dbo.[Master StaffingList] WHERE [Agent Name] = ?"
cmd.CommandType = adCmdText
cmd.Parameters.Append cmd.CreateParameter(Type:=adVarChar, Value:=selectedName)
Set rs = cmd.Execute

Теперь для использования набора записей вы не можете предполагать, что будут строки - поэтому вы создаете цикл Do While, который не входит, если rs.EOF равен True:

Do While Not rs.EOF
    '...consume recordset...
    rs.MoveNext
Loop

Теперь нужно вычислить только selectedName. Для этого используйте свойство listbox 'ListIndex:

Dim selectedName As String
With MainPage.AgentName
    Debug.Assert .MultiSelect = fmMultiSelectSingle 'wheels come off otherwise
    selectedName = .List(.ListIndex)
End With
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...