40

将我使用的 SQL DB 迁移到新服务器后出现问题。现在,当尝试在 Access(表单或表格)中编辑记录时,它会说:WRITE CONFLICT: This record has been changed by another user since you started editing it...

是否有任何不明显的原因。没有其他人使用服务器,我已禁用表上的任何触发器。我刚刚发现这与 NULL 有关,因为没有任何记录是可以的,但是某些具有 NULL 的行则不是。会不会跟索引有关?如果相关,我最近开始每天批量上传,而不是使用 Access 中的 INSERT INTO 一次上传一个。

4

14 回答 14

62

可能出现的问题:

1 并发编辑

一个原因可能是相关记录已在您正在编辑的表单中打开。如果您在编辑会话期间以编程方式更改记录,然后尝试关闭表单(并因此尝试保存记录),则 access 表示该记录已被其他人更改(当然是您,但 Access 不知道)。

在以编程方式更改记录之前保存表单。
在表格中:

'This saves the form's current record
Me.Dirty = False

'Now, make changes to the record programmatically

2 缺少主键或时间戳

确保 SQL-Server 表具有主键和时间戳列。

时间戳列帮助 Access 确定自上次选择后是否已编辑记录。如果没有可用的时间戳,Access 通过检查所有字段来执行此操作。如果没有时间戳列,这可能不适用于空条目(请参阅3 Null bits issue)。

时间戳实际上存储的是行版本号而不是时间。

添加时间戳列后不要忘记刷新access中的表链接,否则Access是看不到的。(注意:将 Access 表转换为 SQL-Server 表时,Microsoft 的升迁向导会创建时间戳列。)


3 空位问题

根据@AlbertD.Kallal 的说法,这可能是此处描述的空位问题:KB280730(WayBackMachine 上的最后一个快照,原始文章已被删除)。如果您使用的是位字段,请将其默认值设置为0并将之前输入的任何 NULL 替换为0。我通常使用BIT DEFAULT 0 NOT NULL布尔字段,因为它最接近布尔的想法。

知识库文章说使用 *.adp 而不是 *.mdb;但是,Microsoft 在 Access 2013 中停止了对 Access Data Projects (ADP) 的支持

于 2012-12-21T16:08:08.093 回答
16

有这个问题,和原来的海报一样。即使直接使用无表单进行编辑。问题出在位字段上,如果您的字段为 Null,当您访问记录时它会将 Null 转换为 0,然后您进行更改,这次是第二次更改。所以这2个变化冲突。我听从了 Olivier 的建议:

“确保表有一个主键和一个时间戳列。”

它解决了这个问题。

于 2013-05-13T18:42:50.330 回答
4

当链接到 MS SQL Sever 2000(和更早版本)时,我已经看到与 MS Access 2003(和更早版本)类似的情况。就我而言,我发现问题出在 MS SQL Server 数据库表中的位字段 - 位字段不允许空值。当我将记录添加到通过 MS Access 2003 链接的表时,数据库窗口将返回错误,除非我专门将位字段设置为 True 或 False。为了补救,我更改了任何 MS SQL Server 数据表,以便任何位字段默认为 0 值或 1。一旦我这样做了,我就可以通过 MS Access 将数据添加/编辑到链接表中。

于 2013-12-17T20:15:51.563 回答
4

由于 Jet/Access 布尔值和 SQL Server 位字段之间的冲突,我发现了问题。

此处在陷阱 #4 https://blogs.office.com/2012/02/17/five-common-pitfalls-when-upgrading-access-to-sql-server/下进行了描述

我编写了一个 SQL 脚本来将所有位字段更改为 NOT NULL 并提供默认值 - 在我的情况下为零。

只需在 SQL Server Management Studio 中执行此操作,然后将结果粘贴到新的查询窗口中并运行它们 - 将其放入游标并执行它几乎不值得。

SELECT
    'UPDATE [' + o.name + '] SET [' + c.name + '] = ISNULL([' + c.name + '], 0);' + 
    'ALTER TABLE [' + o.name + '] ALTER COLUMN [' + c.name + '] BIT NOT NULL;' + 
    'ALTER TABLE [' + o.name + '] ADD  CONSTRAINT [DF_' + o.name + '_' + c.name + '] DEFAULT ((0)) FOR [' + c.name + ']'
FROM
    sys.columns c
INNER JOIN sys.objects o
ON  o.object_id = c.object_id
WHERE
    c.system_type_id = 104
    AND o.is_ms_shipped = 0;
于 2015-12-15T09:58:39.090 回答
1

这是微软的一个错误

若要解决此问题,请使用下列方法之一:

  • 更新基于多表视图的表单 在第一次出现“症状”部分中提到的错误消息时,您必须在“写入冲突”对话框中单击“复制到剪贴板”或“删除更改”。若要避免重复出现"症状"部分中提到的错误消息
    ,您必须在
    再次编辑同一记录之前更新窗体中的记录集。备注 若要更新 Access 2003 或 Access 2002 中的表单,请单击“记录”菜单上的“刷新”。要更新 Access 2007 中的表单,请单击“主页”选项卡上“记录”组中的“全部刷新”。

  • 使用带有链接子表单的主表单 为避免重复出现“症状”部分中提到的错误消息,您可以使用带有
    链接子表单的主表单在相关表中输入数据。您可以从一个位置在两个表中输入
    记录,而无需使用基于多表视图的表单。要创建带有链接子表单的主表单,请执行以下步骤:

    创建一个基于多表视图中使用的相关(子)表的新表单。在表格中包含必填字段。保存窗体,然后关闭窗体。创建一个基于在多表视图中使用的主表的新表单。
    在表格中包含必填字段。在“数据库”窗口中,将您在步骤 2 中保存的表单添加到主表单。

    这将创建一个子表单。
    将子窗体的链接子字段属性和链接主字段属性设置为用于链接表的一个或多个字段的名称。

来自微软支持的变通方法

于 2012-12-21T16:06:19.940 回答
1

我经历了上面详述的两个原因:直接更改当前绑定到表单的表中的数据,并且在 SQL Server 中有一个“位”类型字段,该字段没有将默认值设置为“0”(零)。

我能够解决后一个问题的唯一方法是将默认值零添加到位字段并运行更新查询以将所有当前值设置为零。

为了绕过前一个错误,我必须要有创造力。有时我可以更改 VBA 语句的顺序并将 Refresh 或 Requery 移动到不同的位置,从而防止出现错误消息。然而,在大多数情况下,我所做的是在我调用直接表更新的子例程中对字符串变量进行 DIM 处理。在调用更新之前,我将此字符串变量设置为绑定表单后面的 Recordsource 的值,从而捕获当时正在使用的确切 SQL 语句。然后,我将表单的 Recordsource 设置为空字符串 (""),以便将其与数据断开连接。然后,我执行数据更新。然后,我将表单的 Recordsource 设置回保存在 String 变量中的值,重新建立绑定并允许它获取表中的新值。如果此表单中包含一个或多个子表单,则“链接”字段需要以与 Recordsource 类似的方式处理。当 Recordsource 设置为空字符串时,您可能会在现在未绑定的字段中看到 #Name。我所做的只是在 Recordsource 为空时将 Visible 属性设置为最高级别(详细信息部分、子窗体等)的 False,从而对用户隐藏 #Name 值。当找不到编码更改时,将 Recordsource 设置为空字符串是我的首选解决方案。不过,我想知道,如果我缺乏设计技能,是否有办法完全避免这个问题?您可能会在现在未绑定的字段中看到#Name。我所做的只是在 Recordsource 为空时将 Visible 属性设置为最高级别(详细信息部分、子窗体等)的 False,从而对用户隐藏 #Name 值。当找不到编码更改时,将 Recordsource 设置为空字符串是我的首选解决方案。不过,我想知道,如果我缺乏设计技能,是否有办法完全避免这个问题?您可能会在现在未绑定的字段中看到#Name。我所做的只是在 Recordsource 为空时将 Visible 属性设置为最高级别(详细信息部分、子窗体等)的 False,从而对用户隐藏 #Name 值。当找不到编码更改时,将 Recordsource 设置为空字符串是我的首选解决方案。不过,我想知道,如果我缺乏设计技能,是否有办法完全避免这个问题?

关于解决错误消息的最后一个想法:我没有调用例程直接更新表中的数据,而是找到了一种通过表单更新数据的方法,方法是向表单添加绑定控件并更新数据这样表单数据和表格数据就不会不同步。

于 2017-01-20T21:59:45.280 回答
0

为了克服这个问题。我创建了 VBA 来更改同一行中的另一个字段。因此,我创建了一个单独的字段,当我尝试关闭表单时,它会将 1 添加到内容中。这解决了这个问题。

于 2013-11-21T20:31:14.703 回答
0

我已经多次使用链接到 MS SQL 表的 MS Access 表来处理这个问题。原始发帖人的回应非常有帮助,确实是我许多问题的根源。

当我不小心在字段名中添加了一个带有空格的位字段时,我也遇到了这个问题......是的......

我已经运行了 alter table tablename add [fieldname] bit default 0。我找到的解决方案是删除该字段并且名称中没有空格。

于 2014-05-01T14:58:11.777 回答
0

我遇到了这个问题,并意识到它是由向现有表添加新位字段引起的。我删除了新字段,一切都恢复正常。

于 2014-12-11T19:13:15.683 回答
0

如果您正在使用链接表,请确保您已更新这些表并在执行其他任何操作之前重试。

我以为我已经更新了它们但是没有

不确定这是最适合该场景的错误,但是,大多数有趣的问题从未在任何 Microsoft 软件中正确标记!

于 2017-01-26T13:48:55.100 回答
0

我正在使用这种解决方法,它对我有用:前端:Ms Access 后端:Mysql

在给定字段的更新前事件上:

Private Sub tbl_comuna_id_comuna_BeforeUpdate(Cancel As Integer)

If Me.tbl_comuna_id_comuna.OldValue = Me.tbl_comuna_id_comuna.Value Then
Cancel = True
Undo
End If
End Sub
于 2019-01-14T17:30:31.257 回答
0

我刚刚遇到了非常严重的写入冲突问题(Acc2013 32 位,SQL Srv2017 expr),带有相当“重载”的拆分形式。对我来说 - 最后 - 是摆脱写冲突问题的解决方案

将 AcSplitFormDatasheet 设置为只读!(我不知道为什么它是读写的,我一定是错误地设置了它......)

我几乎花了整整一周的时间才发现这一点。

于 2019-01-24T21:28:53.343 回答
0

我遇到了这个问题并保存了记录,将 Dirty 标记为 false 等都不起作用。最终,向 SQL 表添加时间戳列是避免/解决问题的方法。

于 2021-05-19T19:15:36.170 回答
-2

我收到了同样的错误信息。数据库表中的 Id 列设置为 BigInt,将其更改为 Int 解决了该问题。

于 2016-06-15T04:20:07.843 回答