2015-07-08 2 views
0

Я получил запросы в своей форме и возвращаюсь на общий цикл очистки и параметризовать запросы, и у меня возникают проблемы с одним запросом, который использует LIKE ключевое слово вместе с шаблоном (%). Запросы получают информацию от или работают в базе данных Access. Обратите внимание, что атаки SQL Injection не являются проблемой, поскольку местоположение, в котором выполняется эта форма, не имеет никакого отношения к внешнему миру (нет, ноль, zip). Таким образом, трояны SQL Injection, пожалуйста, воздержитесь.Параметрированный запрос не работает (vb.net, OleDb)

Также обратите внимание, что я не опытный VB'er или .NET'er так делаю то, что я могу на основе поиска через StackOverflow (который оказался чрезвычайно полезным во многих случаях, спасибо всем!)

  1. Значения от Me.cmboAssemblyNum.Text имеют формат X31-D104518-1-00101 - **.
  2. Там всегда будет буквенный знак в начале
  3. Последних символов будут варьироваться от двойной звездочки 2 алфавитных символов (это пересмотр части/чертежа)
    • Я знаю, что двойные звездочки были плохой выбор, но это то, что я должен работать, и он не может изменить
  4. поле фильтруется с LIKE и% будет содержать что-то вроде:
    • Добавлено Х3 1-D104518-1-00101 - **
    • Исключен из X31-D104518-1-00101 - **

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

"SELECT HistoryID, InventoryID, SerialNumber, QuantityChange, TransactionAction, Notes, TransactionDate, TransactionTime 
FROM InventoryHistory 
WHERE ((((InventoryHistory.TransactionAction) Like '%" + Me.cmboAssemblyNum.Text + "') 
AND ((InventoryHistory.Location) = 'INVENTORY')) 
OR (((InventoryHistory.SerialNumber) = '" + Me.cmboAssemblyNum.Text + "') AND ((InventoryHistory.TransactionAction) = 'Assembly is complete')) 
OR ((InventoryHistory.Location) = '" + Me.cmboAssemblyNum.Text + "'))" 

Я параметрироваться запрос следующим образом с использованием @cmboAssemblyNum, но он не работает. Я не получаю никаких ошибок, но запрос не возвращает ожидаемые значения. Опять же, я сформировался для удобочитаемости, и все, что я делал в коде, заключалось в замене «+ Me.cmboAssemblyNum.Text +» на @cmboAssemblyNum.

Я также пробовал следующее с одинарными кавычками и без них. '% @ CmboAssemblyNum.

"SELECT HistoryID, InventoryID, SerialNumber, QuantityChange, TransactionAction, Notes, TransactionDate, TransactionTime 
FROM InventoryHistory 
WHERE (((InventoryHistory.TransactionAction Like %@cmboAssemblyNum) 
AND ((InventoryHistory.Location) = 'INVENTORY')) 
OR (((InventoryHistory.SerialNumber) = @cmboAssemblyNum) 
AND ((InventoryHistory.TransactionAction) = 'Assembly is complete')) 
OR ((InventoryHistory.Location) = @cmboAssemblyNum))" 

Полный код для выполнения этого запроса.

Dim ds As New DataSet 
Dim da As New OleDb.OleDbDataAdapter 

'If an assembly has been started but not completed, get list of items already added 
strSQL = "SELECT HistoryID, InventoryID, SerialNumber, QuantityChange, TransactionAction, Notes, TransactionDate, TransactionTime " & _ 
"FROM InventoryHistory " & _ 
"WHERE (((InventoryHistory.TransactionAction Like %@cmboAssemblyNum) AND ((InventoryHistory.Location) = 'INVENTORY')) OR (((InventoryHistory.SerialNumber) = @cmboAssemblyNum) AND ((InventoryHistory.TransactionAction) = 'Assembly is complete')) OR ((InventoryHistory.Location) = @cmboAssemblyNum))" 

Try 
    'run strSQL statement fills tbl_ExistingTransactions with resulting dataset 
    da.SelectCommand = New OleDb.OleDbCommand(strSQL, Conn_Backend) 
    da.SelectCommand.Parameters.AddWithValue("@cmboAssemblyNum", Me.cmboAssemblyNum.Text) 
    da.Fill(ds) 
    tbl_ExistingTransactions = ds.Tables(0) 

Catch ex As Exception 
    Me.txtStatus.Text = "Caught exception when running strSQL the first time in UpdateDataGridView" 

End Try 

Любая помощь или руководство оценены. Я искал StackOverFlow, а также другие сайты и не нашел ничего, что работает на сегодняшний день.

Я не верю, что могу включить образец таблиц, но если смогу, я это сделаю.

ответ

0

Попробуйте это:

WHERE (((InventoryHistory.TransactionAction Like '%' + @cmboAssemblyNum) 
3

Попробуйте с % подстановочных символов в значении параметра, а не в SQL:

Dim ds As New DataSet 
Dim da As New OleDb.OleDbDataAdapter 

'If an assembly has been started but not completed, get list of items already added 
strSQL = "SELECT HistoryID, InventoryID, SerialNumber, QuantityChange, TransactionAction, Notes, TransactionDate, TransactionTime " & _ 
"FROM InventoryHistory " & _ 
"WHERE (((InventoryHistory.TransactionAction Like @cmboAssemblyNum) AND ((InventoryHistory.Location) = 'INVENTORY')) OR (((InventoryHistory.SerialNumber) = @cmboAssemblyNum) AND ((InventoryHistory.TransactionAction) = 'Assembly is complete')) OR ((InventoryHistory.Location) = @cmboAssemblyNum))" 

Try 
    'run strSQL statement fills tbl_ExistingTransactions with resulting dataset 
    da.SelectCommand = New OleDb.OleDbCommand(strSQL, Conn_Backend) 
    da.SelectCommand.Parameters.AddWithValue("@cmboAssemblyNum", "%" & Me.cmboAssemblyNum.Text) 
    da.Fill(ds) 
    tbl_ExistingTransactions = ds.Tables(0) 

Catch ex As Exception 
    Me.txtStatus.Text = "Caught exception when running strSQL the first time in UpdateDataGridView" 

End Try 
+0

Просто попробовал это, это не сработало. Я начинаю думать, что это может быть не «... как ...», где проблема. С отсутствием ошибки это казалось логичным, потому что мне удавалось параметризовать другие запросы, но у них не было части «... Like ...». – EasyE

0

Я думаю, что разобрался, хотя я не могу объяснить почему это работает. Я создал файл INI и включил следующее в INI, которое я изначально пытался использовать в своем коде (например, заменяя «+ Me.cmboAssemblyNum.Text +» на @cmboAssemblyNum). Я прочитал INI-файл с помощью GetPrivateProfileString и сохранил значение в строке.

sql_tblExistingTransactions="SELECT HistoryID, InventoryID, SerialNumber, QuantityChange, TransactionAction, Notes, TransactionDate, TransactionTime FROM InventoryHistory WHERE ((((InventoryHistory.TransactionAction) Like '%@cmboAssemblyNum.Text') AND ((InventoryHistory.Location) = 'INVENTORY')) OR (((InventoryHistory.SerialNumber) = @cmboAssemblyNum.Text) AND ((InventoryHistory.TransactionAction) = 'Assembly is complete')) OR ((InventoryHistory.Location) = @cmboAssemblyNum.Text))" 

Я побежал мой код как есть в моем вопросе:

da.SelectCommand = New OleDb.OleDbCommand(strSQL, Conn_Backend) 
    da.SelectCommand.Parameters.AddWithValue("@cmboAssemblyNum", Me.cmboAssemblyNum.Text) 
    da.Fill(ds) 
    tbl_ExistingTransactions = ds.Tables(0) 

, и она работала, как ожидалось.

В любом случае мы используем файл INI для запросов, но делаем разработку снаружи, чтобы избежать проблем при обслуживании, в то время как обновления производятся так, что это получается.

Может ли кто-нибудь придумать, почему он будет работать, когда строка считывается из INI-файла, но не работает при использовании встроенного оператора SQL в коде?

Я собираюсь попробовать что-то еще, но я не думаю, что я разобраться, почему это работает.

Смежные вопросы