在MS访问中进行升级

Urb*_*coz 6 sql ms-access upsert

我需要为MS-Access 2000编写SQL查询,以便在存在时更新行,但如果不存在则插入.(我相信这被称为"upsert")

如果行存在...

UPDATE Table1 SET (...) WHERE Column1='SomeValue'
Run Code Online (Sandbox Code Playgroud)

如果它不存在......

INSERT INTO Table1 VALUES (...)
Run Code Online (Sandbox Code Playgroud)

这可以在一个查询中完成吗?

Pat*_*rez 8

可以使用带有的UPDATE查询模拟Access中的upsert LEFT JOIN.

update b
left join a on b.id=a.id
set a.f1=b.f1
, a.f2=b.f2
, a.f3=b.f3
Run Code Online (Sandbox Code Playgroud)

请参阅:https://www.experts-exchange.com/questions/28713136/Can-I-use-the-SQL-MERGE-statement-in-a-query-in-Access-2010.html

  • 为了更清楚地说明,此查询用*来自* b 的值更新 a。(对于新手来说!) (4认同)

Gus*_*tav 7

如果表具有唯一键,则可以进行“更新”。

Smart Access的这一古老技巧是我的最爱之一:

一次查询更新和追加记录

艾伦·比格斯(Alan Biggs)

您是否知道可以在Access中使用更新查询来同时更新和添加记录?如果您有两个版本的表tblOld和tblNew,并且要将tblNew的更改集成到tblOld中,这将很有用。

跟着这些步骤:

创建一个更新查询并添加两个表。通过将tblNew的关键字段拖到tblOld的匹配字段来连接两个表。

  1. 双击关系,然后选择联接选项,其中包括来自tblNew的所有记录,并且仅包括与tblOld匹配的记录。

  2. 从tblOld中选择所有字段,然后将它们拖到QBE网格上。

  3. 对于每个字段,在“更新到”单元格中输入tblNew.FieldName,其中FieldName与tblOld的字段名称匹配。

  4. 从视图菜单中选择查询属性,然后将唯一记录更改为假。(这将关闭SQL视图中的DISTINCTROW选项。如果将其保留,则结果中将仅获得一个空白记录,但您希望将每个新记录的一个空白记录添加到tblOld。)

  5. 运行查询,您将看到对tblNew的更改现在位于tblOld中。

这只会将已添加到tblNew的记录添加到tblOld。tblNew中不存在的tblOld中的记录仍将保留在tblOld中。


Han*_*sUp 5

假设Column1上有唯一索引,您可以使用DCount表达式来确定您是否有零行或一行,其中Column1 ='SomeValue'.然后INSERTUPDATE基于该计数.

If DCount("*", "Table1", "Column1 = 'SomeValue'") = 0 Then
    Debug.Print "do INSERT"
Else
    Debug.Print "do UPDATE"
End If
Run Code Online (Sandbox Code Playgroud)

我更喜欢这种方法,首先尝试INSERT捕获3022密钥违规错误,然后执行UPDATE响应错误.但是,我无法从我的方法中获得巨大的利益.如果您的表包含自动编号字段,则避免失败INSERT将阻止您不必要地消耗下一个自动编号值.我还可以避免INSERT在不需要时构建字符串.Access Cookbook告诉我字符串连接在VBA中是一个中等昂贵的操作,所以我寻找机会避免构建字符串,除非实际需要它们.这种方法也可以避免为不需要的人创建一个锁INSERT.

但是,这些原因中没有一个对您来说非常有吸引力.老实说,我认为在这种情况下我的偏好可能与我的"感觉正确"有关.我同意@ David-W-Fenton前一个Stack Overflow问题的评论:"最好编写你的SQL,这样你就不会尝试追加已经存在的值 - 即,防止错误发生在第一个放置而不是依靠数据库引擎来拯救你."

  • 谢谢你的报价!我完全同意自己的意见!:)无论如何,我使用LEFT JOIN执行此操作,并仅插入尚不存在的记录. (3认同)