使用VBA插入Access DB,尝试排除重复但收到错误

时间:2018-01-18 14:36:39

标签: vba ms-access access-vba

我确定这很简单,但是,我在尝试运行时遇到错误。我创建了一个数据库,想要导入一些数据。我已经解析了导入文件,并将相关数据分配给变量。

下一步是插入我已经管理过的数据库,但是,如果它找到重复的话,我希望它忽略该行。

代码位是: -

strSQL = "INSERT INTO PubHol " & "(HolidayDate, HolidayName)" & " VALUES (""" & dtOutDT & """, """ & strOutDesc & """ )" & " WHERE NOT EXISTS (SELECT * FROM PubHol as ph WHERE ph.HolidayDate = CDate ('" & dtOutDT & "'))"
MsgBox strSQL
dbCurr.Execute strSQL, dbFailOnError

MsgBox显示以下输出: -

---------------------------
Microsoft Access
---------------------------
INSERT INTO PubHol (HolidayDate, HolidayName) VALUES ("01/01/2018", "New Year's Day" ) WHERE NOT EXISTS (SELECT * FROM PubHol as ph WHERE ph.HolidayDate = CDate ('01/01/2018'))

所有这些对我来说似乎都是一个有效的SQL语句,但我得到了一个VB错误

  

运行时错误'3067'查询输入必须至少包含一个表或   查询。

任何人都可以解释我出错的地方吗?

关于避免重复添加到我的数据库的任何其他提示?

由于

2 个答案:

答案 0 :(得分:1)

您不能将INSERT INTO .. VALUES语法与WHERE子句一起使用。 (我猜这是因为WHERE旨在限制插入的记录,这只有在您尝试插入多个记录时才有意义; Access SQL中的VALUES会插入单个记录。)< / p>

理想情况下,您应该应用约束并处理产生的错误,如Parfait's answer

如果你不能这样做,(因为约束只适用于导入而不是常规业务数据,或者出于其他原因),那么要么决定是否INSERT VBA中的记录,而不是在SQL中:

Dim recordCount As Integer
'get the number of records matching the criteria
If recordCount = 0 Then
    'INSERT records here
End If

或者,如果您仍想在SQL中完全执行此操作,我建议如下:

INSERT INTO PubHol (HolidayDate, HolidayName)
SELECT TOP 1 "01/01/2018", "New Year's Day"
FROM dummy
WHERE NOT EXISTS (
    SELECT * 
    FROM PubHol as ph 
    WHERE ph.HolidayDate = CDate ('01/01/2018')
)

dummy是数据库中至少有一条记录的任何表。

NB。您可能想要考虑使用SQL参数;您可以避免必须手动构造字符串和日期文字,还可以避免查询中的日期转换。

此外,您似乎一次只导入一条记录。如果您可以为导入源创建链接表,则最好创建一个INSERT查询,该查询会将链接表中的数据按到目标表的正确形状。

答案 1 :(得分:1)

在Access SQL方言中,如果没有查询中的数据源,则无法运行WHERE。具体而言,您可以在 HolidayDate HolidayName 上禁用重复项的唯一值约束中做得很好:

dbCurr.Execute "ALTER TABLE [PubHol] ADD CONSTRAINT uniq_holiday" _
                 & " UNIQUE (HolidayDate, HolidayName)"

然后运行常规参数化追加查询,其中任何添加重复值的尝试都将作为异常返回并回滚。

SQL (另存为查询对象,可以在其他假期使用)

PARAMETERS [HolidayDateParam] Datetime, [HolidayNameParam] TEXT(255);
INSERT INTO PubHol (HolidayDate, HolidayName)
VALUES ([HolidayDateParam], [HolidayNameParam])

VBA

Dim qdef As QueryDef

...
Set qdef = dbCurr.QueryDefs("mysavedquery")

qdef![HolidayDateParam] = dtOutDT
qdef![HolidayNameParam] = strOutDesc

qdef.Execute dbFailOnError

Set qdef = Nothing