【问题标题】:MS Access - SQL append query behavior is erraticMS Access - SQL 追加查询行为不稳定
【发布时间】:2017-09-06 16:58:37
【问题描述】:

过去几周我一直在研究 Access 数据库,这是我使用该工具的第一个项目。处理追加查询似乎已成为一场彻头彻尾的噩梦,令人难以置信的沮丧。更是如此,因为它似乎只是在一夜之间停止了以任何一致的方式工作。

我写的 SQL 查询是这样的:

PARAMETERS noteDetails LongText, noteTime DateTime, srcUserID Long;
INSERT INTO tblNotes (NOTE_DETAILS, NOTE_TIME_CREATED, NOTE_SOURCE_USER)
VALUES (noteDetails, noteTime, srcUserID)

tblNotes中:

NOTE_ID is an AutoNumber
NOTE_DETAILS is a Long Text
NOTE_TIME_CREATED is a Date/Time
NOTE_SOURCE_USER is a Number

我运行此查询的方式是通过 VBA:

Set qdf = CurrentDb.QueryDefs("qerApndNote")
qdf.Parameters(0).Value = txtDetails.Value
qdf.Parameters(1).Value = Now()
qdf.Parameters(2).Value = getCurrentUserID()
qdf.Execute dbFailOnError
qdf.Close
Set qdf = Nothing

' Where CurrUserID is a global long
' txtDetails.Value is a textbox's contents
' Now() is the VBA built-in function to return a date/time combo

我尝试从导航栏中手动运行此查询,并且以这种方式完成后运行良好。

但是,从 VBA 运行它会导致没有插入时间/日期,有时没有插入用户 ID,有时两者,有时甚至缺少详细信息文本。

我错过了什么?对于 MS Access 的用户,是否有任何我没有遵循的一般性建议?我知道 NOTE 在 Access 中是一个受限词,但我真的认为这不应该适用于这里,对吧?

提前致谢!

编辑:我从中传递数据的表单称为frmNewNote,其中有一个名为txtDetails 的控件。它只是一个普通的文本框。真的不知道还有什么可以分享的。

getCurrentUserID 函数在一个模块中,modGlobal

Public CurrUserID As Long

Public Function getCurrentUserID() As Long
    getCurrentUserID = CurrUserID
End Function

Public Function setCurrentUserID(CurrID As Long)
    CurrUserID = CurrID
End Function

真的,它几乎是你能得到的准系统。并且在您的...会话期间调用 SetCurrentUserID 之前,您永远不会进入表单?涉及到一个登录表单。

@Andre 的日志记录代码:

 0            noteDetailsText             This is a note test
 1            noteTimeCreated             9/6/2017 10:28:45 AM 
 2            srcUserID      1

至于我的架构,嗯,它现在只是桌面上的单个数据库文件。当您单击按钮 btnEnter 时,将运行整个函数/子程序。它在到达 SQL 语句位之前会做一些其他的事情——检查空值并提示用户输入条目。

【问题讨论】:

  • 你没有显示连接到数据库或关闭数据库连接,所以我猜这些部分有问题。
  • 或许可以试试Set cdb = CurrentDb,然后是Set qdf = cdb.QueryDefs("qerApndNote")
  • 我的另一个建议是更改例程以进行一些日志记录——在调用之前记录值,在调用之后记录值,包括时间戳。谜底即将揭晓。
  • 有点长镜头,但尝试按名称而不是索引来寻址参数。 qdf.Parameters("noteDetails").Value = txtDetails.Value
  • 仍然没有填写用户 ID 或日期时间列,不过还是感谢大家的帮助。

标签: sql ms-access vba


【解决方案1】:

我刚刚想起一件事:

MS Access 2013 calling insert queries from VBA with strange errors

你有一个LongText 参数。这些真的不起作用。另见https://stackoverflow.com/a/37052403/3820271

如果输入的注释总是 ShortText。

如果文本可以更长,则必须使用 SunKnight0 的方法和串联的 INSERT 语句。

或者使用 Recordset 及其 .AddNew 方法,这将是与您当前解决方案类似的代码量,但也可以完全避免注入或格式化问题。

【讨论】:

    【解决方案2】:

    你做的工作比你必须做的要多。您只需要:

    DoCmd.RunSQL("INSERT INTO tblNotes (NOTE_DETAILS, NOTE_TIME_CREATED, NOTE_SOURCE_USER) VALUES ('" & Me.txtDetails & "',Now()," & CurrUserID  & ")")
    

    请注意从 txtDetails.ValueMe.txtDetails 的更改,这可能会让您感到困惑。这当然假设代码在表单的上下文中运行,否则您必须使用对表单的引用来获取文本字段的值。

    唯一需要考虑的另一件事是确保Me.txtDetails 没有任何单引号,因此可能改用Replace(Me.txtDetails,"'","''")

    这样,您还可以将DoCmd.RunSQL 替换为MsgBox 以解决确切的查询问题。

    【讨论】:

    • 从到目前为止我所阅读和了解的所有内容来看,这并不是最佳实践。我这样做的方式实际上是 can 在我的字符串中使用单引号,因为查询是参数化的。至少,我认为这是它的要点。
    • 我使用Me. 添加了更多更改。至于最佳实践,它实际上取决于您的环境和系统的开放性。在大多数情况下,当仅处理 Access UI 而不是面向 Internet 的应用程序时,仅使用替换来处理单引号会使生活变得更加轻松,尤其是在代码生成更复杂的查询时。我通常会创建一个简短的函数,调用它类似于 Qs 来处理单引号问题,使代码更具可读性。
    猜你喜欢
    • 1970-01-01
    • 2020-03-20
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    相关资源
    最近更新 更多