【问题标题】:Error 3346, trying to INSERT INTO, two consecutive tables错误 3346,试图 INSERT INTO,两个连续的表
【发布时间】:2018-02-16 03:30:51
【问题描述】:

我有这两张表是 MS Access :

lkpSchemaPIT:

| UID |    lkpSchemaTitleEng     |  
|-----|--------------------------|  
|--1--|---------Title1-----------|  
|--2--|---------Title2-----------|  

...

lkpSchemaPITChronology :

| ID | UID | PUID | Sort | Level | DateStart | DateEnd |  
|----|-----|------|------|-------|-----------|---------|  
|--0-|--1--|--0---|---5--|--2----|---Now()---|--NULL---|  

...

第一个表只包含节点,我将在访问树视图中放入这些节点。我使用第二个表来构建树,但也跟踪节点多年来可能拥有的所有父节点。可以看到两个表中的UID是一样的,但是它们之间没有关系,我在建树的时候,使用了一个带有join的查询。

我的问题是:当我想在 lkpSchemaPIT 表中添加一个新节点时,我还需要能够添加它的“treeview”信息(父级、排序、级别等)。
到目前为止,这是我的代码:

With CurrentDb
      .Execute _
        "INSERT INTO lkpSchemaPIT " & _
          "(lkpSchemaTitleEng) " & _
        "VALUES " & _
          "('" & Title & "')"
      .Execute _
        "INSERT INTO lkpSchemaPITChronology VALUES (" & .OpenRecordset("SELECT @@IDENTITY").Fields(0) & ", " & [ParentID] & ", " & [NewSort] & ", " & [Level] & ", " & Date & ", null)"

End With  

ParentID、NewSort、Level 是在我调用这一切之前已经确定的 3 个变量。 “日期”参数是返回当前日期的 VBA 函数。

我知道第一个 INSERT INTO 正在工作,因为我的表中显示了一个新值。但是第二个 INSERT INTO 不起作用,我得到了错误:

错误 3346 - 查询值和目标字段的数量不同。

有人遇到过这种问题吗?

【问题讨论】:

  • 首先指定要在最后一个查询中插入的列。这通常可以解决问题。
  • 这改变了我得到的错误:3134 - INSERT INTO 中的语法错误。
  • 当它被填写并导致错误时,你能 debug.print 那个字符串吗?
  • 这就是我得到的:INSERT INTO lkpSchemaPITChronology (UID, PUID, Sort, Level, DateStart)VALUES (104, 19, 5, 2, 2018-02-15)
  • 是的,我看到了,改了,但没有任何变化。

标签: sql ms-access vba


【解决方案1】:

再一次,这是一个示例,其中参数化查询将非常宝贵,因为您避免使用引号括起来(包括日期/时间的 #)和将数据和 SQL 混合在一起的字符串连接,从而使代码难以阅读和维护。

MS Access 允许使用 PARAMETERS 子句,您可以在其中定义参数占位符名称和数据类型,然后在 VBA 中,您可以使用 QueryDefs 将值绑定到此类参数。不需要引号或字符串插值。

SQL (将两者都保存为存储查询)

PARAMETERS TitleParam Text(255);
INSERT INTO lkpSchemaPIT (lkpSchemaTitleEng)
VALUES (TitleParam);

PARAMETERS UIDParam Long, PUIDParam Long, SortParam Long, 
           LevelParam Long, DateStart Datetime;
INSERT INTO lkpSchemaPITChronology (UID, PUID, [Sort], [Level], DateStart)
VALUES (UIDParam, PUIDParam, SortParam, LevelParam, DateStartParam);

VBA

...
Dim qdef As QueryDef

With CurrentDb

   ' FIRST QUERY
   Set qdef = .QueryDefs("myFirstSavedAppendQuery")

   qdef!TitleParam = [Title]
   qdef.Execute dbFailOnError

   ' SECOND QUERY
   Set qdef = .QueryDefs("mySecondSavedAppendQuery")

   qdef!UIDParam = .OpenRecordset("SELECT @@IDENTITY").Fields(0)
   qdef!PUIDParam = [ParentID]
   qdef!SortParam = [NewSort]
   qdef!LevelParam = [Level]
   qdef!DateStart = Date()

   qdef.Execute dbFailOnError

End With

Set qdef = Nothing

【讨论】:

  • 太棒了!请注意:参数化是其他语言在使用 SQL 时推荐的行业最佳实践:Java、C#、Python、PHP 等。
猜你喜欢
  • 2012-07-06
  • 2016-09-10
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 2013-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多