如何查询包含单引号的数据库字段?

How do you query a database field containing single quotes?

我在 Classic ASP 工作。我知道有一条记录与我的简单 SQL select 查询匹配。其中包含 ' 字符 '。代码如下:

Fieldname = Replace(trim(Request.form("Fieldname")),"'","'", 1, 10)  
'replace the "'" up to 10 times with the ' code to avoid SQL issues, LOL.

SQL = "select id,fieldname from table where fieldname='"&Trim(Fieldname)&"'"

set rs = server.createobject("adodb.recordset")
rs.open SQL, Application("conn"), 1, 1
If not rs.eof then
    response.redirect "somepage.asp?QS=Fieldname_Exists_in_DB"
Else
    'Sample.hold the value in a hidden input field and pass it to the next page
End If

问题是,我确实知道字段名和字段名值在 MS-SQL 2016 服务器 table 中。我一直从中提取数据。数据库字段中的值包含 ' 值,当它与 SQL 数据库字段进行比较时替换的 FORM 字段名也是如此,因此它不应通过 IF NOT RS.EOF 问题。然而每次都过去了。

我错过了什么?我在这个完全相同的应用程序的其他地方执行完全相同的查询,它的行为符合人们的预期。

试图在评论中进行解释,但由于错过了要点,我将在这里尝试给您举个例子。

不要相信用户输入

ADODB 库交互的经典 ASP 服务器端代码没有任何净化数据的概念。这意味着用户通过 Request 对象 (如 Request.Form("Fieldname") 的任何输入都不应该被信任.

Fieldname = Replace(trim(Request.form("Fieldname")),"'","'", 1, 10)
SQL = "select id,fieldname from table where fieldname='"&Trim(Fieldname)&"'"

这个例子容易受到 SQL Injection 攻击,通常是不好的做法,会导致安全漏洞,可以通过 Internet 上现成的脚本工具轻松利用这些漏洞。

手动清理数据

除了引入的安全漏洞外,由于 SQL 需要构建字符串和其他数据类型的调用方式 (因提供商而异),查询数据也变得更加困难提供商)。必须考虑可能被视为危险或可能破坏查询的各种字符组合可能是一项繁琐的任务,而且当 ADODB 已经有了解决方案时,这种任务在野外经常出现。

参数化查询

ADODB 库有一个名为 ADODB.Command 的内置对象,它消除了所有这些麻烦。

使用问题中的示例,可以编写相同的查询,而无需手动清理数据或直接针对用户输入执行 SQL。

Const adCmdText = 1
Const adVarWChar = 202
Const adParamInput = 1

Dim Fieldname, SQL, cmd, rs, 
Fieldname = Trim(Request.Form("Fieldname") & "")

SQL = "SELECT id, fieldname FROM table WHERE fieldname = ?"

Set cmd = Server.CreateObject("ADODB.Command")
With cmd
  .ActiveConnection = Application("conn")
  .CommandType = adCmdText 'Also can use 1
  .CommandText = SQL
  Call .Append(.CreateParameter("@fieldName", adVarWChar, adParamInput, 255))
  Set rs = .Execute(, Array(Fieldname))
End With
Set cmd = Nothing

If Not rs.EOF then
    response.redirect "somepage.asp?QS=Fieldname_Exists_in_DB"
Else
    'Sample.hold the value in a hidden input field and pass it to the next page
End If

有用的链接

  • A: Using METADATA to Import DLL Constants (展示了一种使用命名常量的方法,不需要在代码中添加您自己的 Const 声明).