我已经在我的表单中运行了查询并返回进行一般清理并参数化查询,并且遇到一个使用LIKE关键字和通配符(%)的查询时遇到问题。查询从Access数据库获取信息或作用于Access数据库。请注意,SQL注入攻击不是问题,因为运行此表单的位置与外部世界没有连接(none,zero,zip)。所以SQL注入巨魔请克制。
另外请注意,我不是一个经验丰富的VB'er或.NET'er,所以我可以根据搜索StackOverFlow做到这一点(已经证明在很多场合都非常有用,谢谢大家!)
查看它有点难看,但原始的,有效的查询文本如下。请注意,我为可读性而格式化,但它可以正常工作,因此任何错别字都不是问题。
"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以下列方式对查询进行了参数化,但它不起作用。我没有得到任何错误,但查询没有返回预期的值。我再次编写了可读性,我在代码中所做的就是用@cmboAssemblyNum替换“+ Me.cmboAssemblyNum.Text +”。
我也尝试了以下有或没有单引号,例如: '%@ 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 :(得分:3)
Try with the %
wildcard character in the parameter value, instead of in the 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
答案 1 :(得分:0)
Try this:
WHERE (((InventoryHistory.TransactionAction Like '%' + @cmboAssemblyNum)
答案 2 :(得分:0)
我想我已将其整理出来,但我无法解释为什么会有效。我创建了一个INI文件,并在INI中包含以下内容,这是我最初在我的代码中尝试的内容(即用@cmboAssemblyNum替换“+ Me.cmboAssemblyNum.Text +”)。我使用GetPrivateProfileString读取INI文件并将值存储在字符串中。
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语句时不起作用?
我会尝试其他一些事情,但我认为我不会理清为什么这样做。