VBA SQL 缺少 WHERE 子句的最后一个条件

Posted

技术标签:

【中文标题】VBA SQL 缺少 WHERE 子句的最后一个条件【英文标题】:VBA SQL missing last condition of WHERE clause 【发布时间】:2018-06-22 08:05:55 【问题描述】:

我已经拔掉了我遗漏的最后一点,试图获得我认为通过 VBA 运行的相当简单的 SQL 语句。当语句的字符串编译时,它会切断 WHERE 子句的最后一个条件,我不知道如何修复它。请帮忙!

我的 SQL 字符串如下所示:

sSQL = "UPDATE Allocations SET WithdrawalDate =" & dThisWithdrawDate & ",Notes = '" & sNotes & "' WHERE StaffID =" & lID & " AND PatientID = " & lThisPatientID & ";"

字符串与 StaffID 变量一起编译并切断子句的 AND 部分。我做错了什么?

【问题讨论】:

你需要养成使用参数的习惯。 SQL 连接很危险。 一旦我得到它的工作,我可以尝试使用参数重构它。它用于非常有限的(本地)使用,因此风险非常低。谢谢你的建议:) 因为您正在使用字符串连接,所以您的 sNotes 字符串中的某些内容(撇号或回车符?)可能会以某种方式提前终止 SQL 语句。如果您想诊断问题,请向我们展示 sSQL 的确切值,或者使用适当的参数再试一次,看看问题是否消失。请记住,这不仅仅是安全问题。例如,如果您的笔记中有“不要”一词(撇号是单引号字符),那么您的语句将不起作用,因为' 将关闭Notes = ...' 的打开引号 马特,我想你已经为我解决了这个问题。我的笔记字符串中有一个撇号。我提供了一个没有标点符号的注释字符串,它可以按照我的需要解析 SQL 语句,谢谢! @DarrenBartrup-Cook :) 一个老歌,但很好看。 【参考方案1】:

@Kostas 建议的另一种方法是使用参数:

Sub Test()

    Dim dThisWithdrawDate As Date
    Dim sNotes As String
    Dim lID As Long
    Dim lThisPatientID As Long

    dThisWithdrawDate = DateSerial(2018, 6, 10)
    sNotes = "This note's not possible without hassle in string concat."
    lID = 1
    lThisPatientID = 2

    With CurrentDb.CreateQueryDef("", _
        "Parameters WithdrawDate DateTime, PatientNotes Text(255), " & _
        "StaffIdentifier Long, PatientIdentifier Long; " & _
        "UPDATE Allocations SET WithdrawalDate = WithDrawDate, Notes = PatientNotes " & _
        "WHERE StaffID = StaffIdentifier AND PatientID = PatientIdentifier")

        .Parameters("WithdrawDate") = dThisWithdrawDate
        .Parameters("PatientNotes") = sNotes
        .Parameters("StaffIdentifier") = lID
        .Parameters("PatientIdentifier") = lThisPatientID
        .Execute

    End With

End Sub

如果使用存储查询,您也可以使用类似:With db.QueryDefs("DML_Update_AllocationTable")

【讨论】:

谢谢达伦,无论如何我稍后会看看如何使用参数来做这件事,这看起来是一种更好的方法来做我想做的事情!【参考方案2】:

尝试以某种可复制的方式进行:

Public Sub TestMe()

    Dim sSql As String
    Dim dThisWithdrawDate As String: dThisWithdrawDate = "foo"
    Dim sNotes As String: sNotes = "bar"
    Dim lID As Long: lID = 5
    Dim lThisPatientID As Long: lThisPatientID = 10

    sSql = "UPDATE Allocations SET WithdrawalDate =" & dThisWithdrawDate & ",Notes = '" & sNotes & "' WHERE StaffID =" & lID & " AND PatientID = " & lThisPatientID & ";"
    Debug.Print sSql

End Sub

上面的代码打印出来:

UPDATE Allocations SET WithdrawalDate =foo,Notes = 'bar' WHERE StaffID =5 AND PatientID = 10;

因此,AND 子句从其他地方被切断。

【讨论】:

感谢 Vityata。这很奇怪,因为我在字符串 sSQL 上添加了一个中断和一个监视,这是一个如上所述的简单赋值,并且在赋值后立即字符串值为:“UPDATE [Allocations] SET WithdrawalDate =22/06/2018 ,Notes = 'some text' WHERE StaffID =10 - 缺少 PatientID @MrCholmondleyWarner 那是有效的 SQL 吗?在大多数数据库中,我希望日期值需要引号。 我还没有走那么远,马特,它可能是无效的。我只是连接了一个日期变量以将其添加到字符串中,因此它是 VBA 生成的任何内容。听起来我需要用引号括起来......我现在知道它为什么不运行了:D

以上是关于VBA SQL 缺少 WHERE 子句的最后一个条件的主要内容,如果未能解决你的问题,请参考以下文章

OUTER JOIN 结果缺少行,没有 WHERE 子句(找到解决方法)

sql请求中的where子句应该最后解决

在 WHERE 子句中使用 OR 的慢速 JOIN 查询 - 缺少可能的索引?

在 WHERE IN 子句 SQL 中显示每条记录的 MAX 日期

Oracle初级优化sql

我需要从 SQL Server 查询中获取前 5 条记录,但要计算满足 where 子句条件的所有记录