【问题标题】:Fail to Append due to Key Violations由于密钥违规而无法追加
【发布时间】:2014-01-02 18:40:00
【问题描述】:

这是我第一次开发数据库,​​也是第一次使用 MS Access!我正在尝试通过链接到查询的表单将 1 条新记录附加到表中。

Private Sub cmdAdjustStock_Click()
'Declare Vars
Dim newqty As Long
Dim Qty As Control
Dim change As Control
Dim BoxType As Control
Dim sql As String

'Set form controls to vars
Set Qty = Forms!formMain!txtQty
Set change = Forms!formMain!txtQtyChange
Set BoxType = Forms!formMain!txtBoxType

'Arithmetic and SQL
newqty = Qty + change
sql = "INSERT INTO tblHistory (BoxType, QtyChange, NewQty) VALUES ('&BoxType&','&change&','&newqty&')"

MsgBox "New Quantity = " & newqty & ", Box Type = " & BoxType 'For Debugging
DoCmd.RunSQL sql

End Sub

“tblHistory”有以下字段:PID、logDate、BoxType、QtyChange、NewQty。必填项。 "logDate" 默认值 = Date() 并且 PID 是自动编号。 “tblHistory”目前没有记录,这个追加将是第一个!

“BoxType”与包含 BoxType(Primary)的主列表及其相应数量的表“tblBoxList”的一对多关系的多端。

My MsgBox 显示正确的数量值和表单中的 BoxType(即“RMA-834”)与“tblBoxList”上的主 BoxType ('RMA-834') 匹配。

通过 MsgBox 验证数据后,Append 由于 1 个密钥违规而失败。我假设此违规与 PID(这是一个自动增量编号)或从表单传递的 BoxType 以某种方式与 tblBoxList 中的主节点不匹配有关。这令人困惑,因为 MsgBox 显示的值看起来与 Primary 相同。

仅供参考:此项目中的表已链接。我在网络上的“后端”中有 3 个表。这是只有表单的“前端”。

【问题讨论】:

    标签: sql ms-access ms-access-2007 vba


    【解决方案1】:

    这是行不通的:

    sql = "INSERT INTO tblHistory (BoxType, QtyChange, NewQty) VALUES ('&BoxType&','&change&','&newqty&')"
    

    尝试将其更改为:

    sql = "INSERT INTO tblHistory (BoxType, QtyChange, NewQty) VALUES ('" & BoxType & "','" & change & "','" & newqty & "')"
    

    【讨论】:

    • 这是我的大部分问题所在。如何正确引用对象。你能解释一下'&BoxType&' '" & BoxType &"'@Johnny Bones之间的区别
    • 您的变量必须在您的报价之外。您首先关闭引号,然后用&符号包围您的变量,然后重新打开引号。我很难解释,但是一旦你认出了这种模式,它就很有意义了。如果变量返回文本,则使用单引号,如果返回整数,则不使用引号。所以,如果 BoxType 是一个整数,它会是 " & BoxType & ",如果它是一个文本,它会是 ' " & BoxType & " ' (在单引号和双引号之间没有额外的空格,我只是把它们放进去,所以你可以看到他们)。
    【解决方案2】:

    检查您要求 Access 执行的 INSERT 语句。

    sql = "INSERT INTO tblHistory (BoxType, QtyChange, NewQty) VALUES ('&BoxType&','&change&','&newqty&')"
    Debug.Print sql
    

    运行代码并检查即时窗口中的INSERT 语句。你可以用 Ctrl+g 去那里。

    您可以复制语句文本并将其粘贴到新 Access 查询的 SQL 视图中进行测试,这将有助于您诊断问题。如果您需要我们的更多帮助,请将语句文本粘贴到您的问题中。

    还可以考虑将INSERT 转换为参数查询。您可以在 VBA 代码中使用该命名查询并在运行时提供参数值。

    假设您创建并测试了一个类似于下面的参数查询,您将其命名为 qryHistoryAppend,它包括 pBoxTypepQtyChangepNewQty 作为命名参数,您可以在 VBA 中打开该查询(QueryDef 对象),提供参数值并执行它。

    Const cstrQuery As String = "qryHistoryAppend"
    Dim db As DAO.Database
    Dim qdf As DAO.QueryDef
    Set db = CurrentDb
    Set qdf = db.QueryDefs(cstrQuery)
    qdf.Parameters("pBoxType") = Forms!formMain!txtBoxType
    qdf.Parameters("pQtyChange") = Forms!formMain!txtQtyChange
    qdf.Parameters("pNewQty") = Forms!formMain!txtQty
    qdf.Execute dbFailOnError ' <- always use Execute instead of DoCmd.RunSQL
    

    请注意,如果该代码包含在 formMain 中,您可以引用 Me!txtBoxType 之类的文本框,而不是 Forms!formMain!txtBoxType

    我对 qryHistoryAppend 的想法是这样的。根据需要进行调整。

    INSERT INTO tblHistory (BoxType, QtyChange, NewQty)
    VALUES (pBoxType, pQtyChange, pNewQty);
    

    【讨论】:

    • 非常有意义。我认为我传递给 sql 语句的变量并非如此。我如何能够将本地声明的输入依赖变量的值作为 SQL Append 参数传递? @HansUp 谢谢一堆!
    • 感谢您的帮助@HansUp!
    • 仅供参考。我在 vba 中引用对象的过程很糟糕(可能是因为我是菜鸟)。无论如何,在我用'&BoxType&'包围参数之前,我只是将它们称为“..Values(BoxType,)”等......而且我会在运行时提示'change'和'newqty'值并且可以成功追加新记录。现在我对使用 access/vba 引用对象的理解完全融化了哈哈。 @hansUp
    • 我非常感谢你让我朝着正确的方向前进!我发现这篇 Microsoft 文章 Everything About Using Parameters
    • 不客气。如果您仍然遇到任何键违规,请将插入值与已存储在具有唯一索引的字段中的值进行比较(主键是一种类型,但不是唯一一种)。如果该表定义并强制执行了关系,则那里的故障也可能触发键冲突错误。
    【解决方案3】:

    根据错误消息,听起来您在此处显示的 VB 代码是无关紧要的。在 MS Access 中打开数据库文件,并首先在 Access 中进行查询。

    【讨论】:

    • 我希望能够在不使用 VBA 的情况下完成这项工作。我无法弄清楚如何引用查询绑定表单控件值并将它们附加到第三个表“tblHistory”(例如我的表单控件“txtBoxType”,它绑定到表“tblCaseList”和“tblBoxList”的内部连接查询' on 'BoxType') 作为 SQL 附加字符串的参数。因此,我尊重使用“代码生成器”将表单控制值传递给本地子变量,然后在我的 sql 附加字符串中引用这些值。
    猜你喜欢
    • 1970-01-01
    • 2021-02-23
    • 1970-01-01
    • 2016-07-17
    • 1970-01-01
    • 2012-11-01
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多