我使用的SQL DB迁移到新服务器后出现问题。现在,当尝试在Access(表单或表格)中编辑记录时,它会显示:WRITE CONFLICT: This record has been changed by another user since you started editing it...
这有什么不明显的原因。没有人使用服务器,我已禁用表上的任何触发器。我刚刚发现它与NULL有关,因为没有的记录没有,但是有些NULL的行不是。可能与索引有关吗?如果它是相关的,我最近开始每天上传BULK,而不是使用来自Access的INSERT INTO一次一个。
答案 0 :(得分:42)
可能出现的问题:
1并发编辑
原因可能是有问题的记录已在您正在编辑的表单中打开。如果在编辑会话期间以编程方式更改记录,然后尝试关闭表单(从而尝试保存记录),则访问权限表明该记录已被其他人更改。
在以编程方式更改记录之前保存表单 形式如下:
'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将无法看到它。 (注意:Microsoft的升迁向导在将Access表转换为SQL-Server表时创建时间戳列。)
3个空位问题
根据@ AlbertD.Kallal,这可能是这里描述的空位问题:KB280730。如果您使用位字段,请将其默认值设置为0
并替换之前输入的0
之前的任何NULL。我通常使用BIT DEFAULT 0 NOT NULL
作为布尔字段,因为它最接近布尔的想法。
知识库文章说使用* .adp而不是* .mdb;但是,Microsoft discontinued the support for Access Data Projects (ADP) in Access 2013。
答案 1 :(得分:11)
有这个问题,和原版海报一样。即使在没有表格的情况下直接编辑。问题出在位字段上,如果您的字段为Null,则在您访问记录时将Null转换为0,然后您进行更改,这次是第二次更改。所以2改变了冲突。我按照奥利维尔的建议:
“确保该表格包含主键以及时间戳列。”
它解决了这个问题。
答案 2 :(得分:3)
当链接到MS SQL Sever 2000(和之前的版本)时,我已经看到与MS Access 2003(和之前)类似的情况。在我的情况下,我发现问题是MS SQL Server数据库表中的位字段 - 位字段不允许空值。当我将记录添加到通过MS Access 2003数据库窗口链接的表时,除非我专门将位字段设置为True或False,否则将返回错误。为了解决这个问题,我更改了任何MS SQL Server数据表,以便任何位字段默认为0值或1.一旦我这样做,我就可以通过MS Access将数据添加/编辑到链接表。
答案 3 :(得分:2)
由于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;
答案 4 :(得分:1)
这是Microsoft的错误
要解决此问题,请使用以下方法之一:
更新基于多表视图的表单
在第一次出现“症状”部分中提到的错误消息时,您必须单击复制到剪贴板或
“写入冲突”对话框中的“删除更改”。避免重复
发生“症状”中提到的错误消息
部分,您必须在编辑之前更新表单中的记录集
同样的记录。
笔记
若要在Access 2003或Access 2002中更新窗体,请单击“记录”菜单上的“刷新”。
若要更新Access 2007中的表单,请单击“主页”选项卡上“记录”组中的“全部刷新”。
使用带有链接子表单的主表单
为避免重复出现“症状”部分中提到的错误消息,您可以使用带有
的主表单
链接子表单以在相关表中输入数据。你可以输入
从一个位置记录两个表中的记录而不使用表单
基于多表视图。
要创建包含链接子表单的主窗体,请按照下列步骤操作:
创建一个基于多表视图中使用的相关(子)表的新表单。包括必填字段 在表格上。 保存表单,然后关闭表单。 创建一个基于多表视图中使用的主表的新表单。在中包含必填字段 形成。 在“数据库”窗口中,将您在步骤2中保存的表单添加到主表单中。
这会创建一个子表单。 将子窗体的“链接子字段”属性和“链接主字段”属性设置为字段的名称 用于链接表格。
答案 5 :(得分:1)
我遇到了上面详述的两个原因:直接更改当前绑定到表单并且具有'' SQL Server中的类型字段没有将默认值设置为' 0' (零)。
我能解决后一个问题的唯一方法是将默认值零添加到位字段并运行更新查询以将所有当前值设置为零。
为了解决前一个错误,我必须具有创造性。有时我可以更改VBA语句的顺序,并将Refresh或Requery移动到其他位置,从而防止出现错误消息。但是,在大多数情况下,我所做的是子程序中的DIM a String变量,我调用直接表更新。在我调用更新之前,我将此String变量设置为绑定表单后面的Recordsource的值,从而捕获当时正在使用的确切SQL语句。然后,我将表单的Recordsource设置为空字符串(""),以便将其与数据断开连接。然后,我执行数据更新。然后,我将表单的Recordsource设置回String变量中保存的值,重新建立绑定并允许它获取表中的新值。如果此表单中包含一个或多个子表单,则"链接"字段需要以与Recordsource类似的方式处理。当Recordsource设置为空字符串时,您可能会在now-unbound字段中看到#Name。我所做的只是在Recordsource为空的时间内将Visible属性设置为最高级别(Detail部分,Subform等)的False,从而隐藏用户的#Name值。当无法找到编码更改时,将Recordsource设置为空字符串是我的首选解决方案。不过,我想知道,如果我的设计技巧缺乏,有办法完全避免这个问题吗?
关于解决错误消息的最后一个想法:我找到了一种通过表单更新数据的方法,而不是调用例程直接更新表格中的数据,方法是向表单添加绑定控件并更新其中的数据使表单数据和表格数据不会失去同步。
答案 6 :(得分:0)
为了克服这个问题。我创建了VBA以更改同一行中的另一个字段。所以我创建了一个单独的字段,当我尝试关闭表单时,它会在内容中添加1。这解决了这个问题。
答案 7 :(得分:0)
我已经多次使用链接到MS SQL表的MS Access表处理了这个问题。原始海报的反应非常有用,确实是我的大部分问题的来源。
当我意外地在fieldname中添加了一个带有空格的位字段时,我也碰到了这个问题......是的....
我已经运行了alter table tablename add [fieldname] bit default 0.我找到的解决办法是删除该字段并且名称中没有空格。
答案 8 :(得分:0)
我遇到了这个问题并意识到这是因为在现有表中添加了一个新的位字段。我删除了新字段,一切都恢复正常。
答案 9 :(得分:0)
如果您使用链接表,请确保已更新这些表并在执行任何其他操作之前重试。
我以为我已经更新了它们但是没有,原来有人更新了表格验证和SQL表格以允许150个字符,但没有刷新链接表因此访问只看到50个字符允许 - Boom写冲突< / p>
不确定这是该方案最合适的错误,但是,大多数有趣的问题在任何微软软件中都没有被正确标记!
答案 10 :(得分:0)
我正在使用此替代方法,它对我有用: 前端: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
答案 11 :(得分:0)
我只是遇到了非常严重的写冲突问题(Acc2013 32位,SQL Srv2017 expr),并且具有“重负载”拆分表。 对我来说-终于-摆脱了简单的写冲突问题的解决方案
将AcSplitFormDatasheet设置为只读! (我不知道为什么它无论如何都是读写的,我一定是由错误设置的...)
我花了整整一个星期的时间才找出来。
答案 12 :(得分:0)
我遇到了这个问题,保存记录、将脏标记为假等都不起作用。最终,向 SQL 表添加时间戳列是避免/解决问题的方法。
答案 13 :(得分:-2)
我收到了同样的错误消息。 数据库表中的Id列设置为BigInt,将其更改为Int解决了问题。