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 子句(找到解决方法)
在 WHERE 子句中使用 OR 的慢速 JOIN 查询 - 缺少可能的索引?