OleDb SQLDATASOURCE 无法选择通配符数据



我的任务是将sql参数应用于被识别为具有sql注入点的网页。发起人使用典型的内联sql字符串进行通配符搜索。我在Stackoverflow中读过很多关于尝试几种选择方法和使用不同串联方法的文章。我已经确定了一种似乎最合理的方法,尽管我对其他建议持开放态度。我知道,由于该页面使用OleDb连接,将被@参数替换为?。

原始vb源选择:

VendorsSDS.SelectCommand = "Select ... and vnmdesc like '%" & UCase(Trim(txtRefine.Text)) & "%'"

原始aspx:

<asp:TextBox ID="txtRefine" name="txtRedfine" runat="server" Width="163px" MaxLength="5"></asp:TextBox>
<asp:ListBox ID="ListBox1" runat="server" DataSourceID="VendorsSDS"
DataTextField="VNMDESC" DataValueField="VENDORID" Height="206px" Width="463px" AutoPostBack="True"></asp:ListBox>
<asp:SqlDataSource ID="VendorsSDS" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString5 %>"
ProviderName="<%$ ConnectionStrings:ConnectionString5.ProviderName %>" 
SelectCommand="Select VNMKVPRE||VNMKVNBR as VendorID, vnmdesc||' - '||VNMKVPRE||VNMKVNBR as vnmdesc from trmsd.avnmp   where VNMST = 'A' and not trim(vnmdesc) = '' and vnmkvpre in ( 'R', 'V', 'X')  order by VNMDESC ">
</asp:SqlDataSource>

我的方向是利用<asp:SelectParameters>以及<asp:ControlParameter>使用txt罚款文本框。

更新aspx:

<asp:SqlDataSource ID="VendorsSDS" runat="server"        
SelectCommand="Select VNMKVPRE||VNMKVNBR as VendorID, vnmdesc||' - '||VNMKVPRE||VNMKVNBR as vnmdesc    from trmsd.avnmp   where VNMST = 'A' and not trim(vnmdesc) = '' and vnmkvpre in ( 'R', 'V', 'X')  order by VNMDESC ">
<SelectParameters>
<asp:ControlParameter ControlID="ctl00$ContentPlaceHolder1$txtRefine" Name="?" PropertyName="Text" defaultvalue=""/>
</SelectParameters>
</asp:SqlDataSource>

更新的vb:

Protected Sub btnRefine_Click(sender As Object, e As System.EventArgs) Handles btnRefine.Click
'   2020-Jul-27 Removed
'   VendorsSDS.SelectCommand = "Select VNMKVPRE||VNMKVNBR as VendorID, vnmdesc||' - '||VNMKVPRE||VNMKVNBR as vnmdesc    from trmsd.avnmp   where VNMST = 'A' and not trim(vnmdesc) = '' and vnmkvpre in ('R', 'V', 'X') and vnmdesc like '%" & UCase(Trim(txtRefine.Text)) & "%' order by VNMDESC "        
'
'   2020-Jul-27  Added sqlinjection monitoring
'
Dim wParm As String = Me.txtRefine.Text
If oSec.IsInputOk(wParm) Then
Me.txtRefine.Text = wParm
'
'   2020-Jul-27 Apply sql parameter usage
'
VendorsSDS.SelectCommand = "Select VNMKVPRE||VNMKVNBR as VendorID, vnmdesc||' - '||VNMKVPRE||VNMKVNBR as vnmdesc    from trmsd.avnmp   where VNMST = 'A' and not trim(vnmdesc) = '' and vnmkvpre in ('R', 'V', 'X') and vnmdesc like ('%' & ? & '%') order by VNMDESC "
VendorsSDS.DataBind()
ListBox1.DataBind()
Else
Me.txtRefine.Text = ""
End If
End Sub

我已经尝试了几种如何应用通配符选择的组合。一些帖子说要使用&其他人说+。这两种策略在绑定发生时无论组合如何都会失败:

System.Data.OleDb.OleDbException: 'SQL0104: Token '%' was not valid. Valid tokens: (.

原因…..:在标记"%"处检测到语法错误。令牌"%"不是有效的令牌。

因此,以下内容都不起作用,我需要比我聪明的人帮助我填补知识空白

and vnmdesc like '%' + ? + '%'
and vnmdesc like ('%' + ? + '%') 
and vnmdesc like ('%' & ? & '%') 
and vnmdesc like ('%?%') 

最后,当页面第一次显示时,它应该使用sqldatasource中的初始sql来显示所有不为空的记录,但现在更新后的sqldatasource也不起作用。

任何建议都将不胜感激!

您实际上有两个错误,这使解决问题变得更加困难。

  1. 您的参数名称不能是?。选择任意名称,如下所示:

    <asp:ControlParameter ControlID="ctl00$ContentPlaceHolder1$txtRefine"
    Name="vnmdescription" PropertyName="Text" defaultvalue=""/>
    
  2. 您的SQL非常接近,但&是VB.NET的连接符。SQL使用+如下:

    VendorsSDS.SelectCommand = "SELECT VNMKVPRE||VNMKVNBR as VendorID, vnmdesc||' - '||VNMKVPRE||VNMKVNBR as vnmdesc
    FROM trmsd.avnmp
    WHERE VNMST = 'A' and not trim(vnmdesc) = '' and vnmkvpre in ('R', 'V', 'X') 
    and vnmdesc like ('%' + ? + '%')
    ORDER BY vnmdesc"
    

有关更多信息,请访问MSDN文档。https://learn.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.sqldatasource.selectparameters?view=netframework-4.8

又尝试了一天的各种想法。。。答案如下:

在vb端:

CONCAT(CONCAT('%', ?), '%')

感谢所有在这件事上帮助我的人。

参数化查询实际上意味着使用SQL命令对象的参数部分。编写查询时,不要将字符串连接到一个长字符串中。比方说,你有一个像奥布莱恩这样的人的名字,名字中有一句引号。现在,由于引号不匹配,查询失败。

不同的数据库(您的数据库没有标明,如MySQL、SQL Server、Oracle等(允许命名参数。其他人使用"作为参数的占位符,并且参数需要以与"占位符。

此外,对于通配符搜索,使用"%"在根据需要添加参数时,可以将正在查找的前/后文本添加到字符串中。

正如我在最初的评论中所提到的,我不知道你的"|"管道字符是for,所以我将为您制作一个示例查询和参数示例。请注意,以这种方式开始的参数与日期、日期/时间、字符串、数字等数据类型无关。您不是将字符串连接在一起。

(注意,多行SQL语句的格式对VB来说是不正确的语法,只是为了可读性(

Dim cmd As New OleDb.OleDbCommand()
cmd.CommandText = 
"SELECT whateverColumn 
FROM YourTable 
WHERE ColumnBeingFiltered = ? 
and SomeCityColumn = ?"
cmd.Parameters.AddWithValue("parmForFirstWhereCondition", variableFromYourCleansedWebPost )
cmd.Parameters.AddWithValue("parmForCity", anotherVariableFromPost )

请注意,查询是什么…"是参数的占位符。然后我按顺序添加参数。我可以命名它们以供参考,所以如果我需要更改它们,例如在循环中,我可以将它们称为

cmd.Parameters["parmForCity"].Value = "Boston"

如果您使用其他数据库,如SQL Server,允许命名参数,则可以命名占位符字段,如…

Dim cmd As New OleDb.OleDbCommand()
cmd.CommandText = 
"SELECT whateverColumn 
FROM YourTable 
WHERE ColumnBeingFiltered = @parmForFirstWhereCondition 
and SomeCityColumn LIKE @parmForCity 
and Population > @parmNumber"
cmd.Parameters.AddWithValue("parmNumber", 125000 )
cmd.Parameters.AddWithValue("parmForCity", "%" & anotherVariableFromPost & "%")
cmd.Parameters.AddWithValue("parmForFirstWhereCondition", variableFromYourCleansedWebPost )

注意,在第二个查询中,我还做了添加"%"对于参数的通配符搜索,添加了第三个基于数字的参数,还更改了参数的顺序,以显示不同SQL引擎在NAMING参数时允许的差异。"@"在SQL server中被识别为命名参数,但实际的参数名称不使用"@&";。此外,我尝试总是在参数名称前面加上"或";p〃;或";parm";以区分实际列与参数。例如:其中";firstName=firstName"vs";firstName=@parmFirstName";,则在查看查询时不存在歧义。

这是否有助于现在为您澄清参数化查询。

最新更新