【问题标题】:Result of strSQL in VBA (Access 2003)VBA 中 strSQL 的结果 (Access 2003)
【发布时间】:2011-12-24 22:34:43
【问题描述】:

我正在制作一个表格来向我的数据库中添加一些记录,但我遇到了一些问题。如果用户填写名为“产品”的字段,我想通过显示一张图片来通知他该产品在数据库中。 (我只是想告诉他-不要禁止添加选项)

我有这段代码,不幸的是它给了我一个错误(运行时错误没有运算符)

Private Sub ProductText_LostFocus()
Dim cnn as New ADODB.Connection
Dim strSQL as String
Dim rs as New ADODB.Recordset
Set cnn = CurrentProject.Connection
strSQL = "Select Product FROM Shopping WHERE Product = " & ProductText.Value
Set rs = cnn.Execute(strSQL)
If rs.RecordCount > 0 then
ShowPicture.Visible = True
End if
End sub

我做错了什么?

【问题讨论】:

  • 如果“Pruduct”不是数字,则该值需要用单引号括起来。 ...WHERE Product = '" & ProductText.Value & "'"
  • 好的,谢谢它没有提示任何错误,但我看不到效果 - 图片仍然不可见(无论产品是否在数据库中),例如颜色TextField 不会变红。怎么了?!
  • 测试 rs.EOF 不是 Recordcount。如果没有匹配,则 rs.EOF 将为 True。
  • 不要假设 Access(ACE、Jet 等)对SQL injection 免疫。

标签: sql vba ms-access-2003


【解决方案1】:

如果您将Command 对象与强类型Parameter 对象一起使用,您将不必担心在参数值中包含或转义引号,而且您可以免受SQL injection 的影响。

在这里,我已经稍微简化了您的代码,并假设您的 Product 列是 NVARCHAR(255) 即可变宽度 Unicode(无压缩)文本:

Private Sub ProductText_LostFocus()
  Dim cmd As New ADODB.Command
  With cmd
    Set .ActiveConnection = CurrentProject.Connection
    .CommandText = "Select Product FROM Shopping WHERE Product = ?;"
    .CommandType = adCmdText
    .Parameters.Append .CreateParameter(, adVarWChar, , 255, ProductText.Value)
    If Not .Execute().EOF Then
      ShowPicture.Visible = True
    End If
  End With
End Sub

【讨论】:

    【解决方案2】:

    您有几个不同的问题。

    首先,不要创建 cnn 和 rs 的新实例,因为它们将在以后设置或创建:

    Dim cnn as ADODB.Connection
    Dim strSQL as String
    Dim rs as ADODB.Recordset
    

    其次,需要在SQL中用引号将产品括起来(如果producttext中包含单引号,可能需要做额外的工作):

    strSQL = "Select Product FROM Shopping WHERE Product = '" & ProductText.Value & "'"
    

    【讨论】:

    • OpenRecordset 是一种 DAO 方法。对于 ADO,Execute 应该可以工作。但我不愿意编辑你的答案来纠正这个问题,因为我认为你关于处理引号的建议是不正确的,即他们应该使用 Command 对象和 Parameter 对象,允许 OLE DB 提供程序转义引号等。唐'不要假设 Access(ACE、Jet 等)对SQL injection 免疫。
    • 对不起,当我看到记录集时,我闪回到 vb6 天。我已经更正了答案。我完全同意命令对象推荐和 SQL 注入,但我只是试图回答具体问题而没有纠正代码的所有问题(它们也应该有异常处理,应该在完成时关闭记录集,并且应该真的更改查询,使其返回单个值(例如 count(1)),以便他们可以使用 adExecuteRecord 选项返回 Record 而不是 Recordset)。
    • 关于使用 COUNT() 和错误处理的好点,但我似乎无法使用 adExecuteRecord 选项返回记录:使用 Command 对象时出现错误,“对象或提供程序不是能够执行请求的操作”并且使用我得到的 Connection 对象,“参数类型错误,超出可接受范围,或者相互冲突。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-06
    相关资源
    最近更新 更多