What can cause a sporadic "-2147352567 The data has been changed" error? - ms-access

One of our forms keeps generating this error message sporadically. The issue occurs on our Order form, which is bound to a linked SQL Server 2008 table. Having printed an advice note (using a report), the order status is then set to 'Printed Order'. At this point, I'm sporadically seeing a "-2147352567 The data has been changed" error. I would say 95% of the time, this doesn't occur, but it's that other 5% that's causing us headaches (and numerous support calls).
Oddly, closing the form and trying the same action on the order causes the same error message, but closing the database and trying again works fine.
It's as if there are some uncommitted changes to the table/record the form is bound to, which exist even when there are no forms, reports, etc open.
The code looks like this:
Select Case Me.txtCurrentStatus
Case NEW_ORDER, UNPRINTED_ORDER:
Me.txtCurrentStatus = PRINTED_ORDER
End Select
'Commit changes
If Me.Dirty = True Then Me.Dirty = False

#iDevelop actually prompted me to look into adding a timestamp to the table, so I take only partial credit ;)...
In short - when using linked tables in Microsoft Access, if the table does not contain a column of type timestamp, Access will compare every column in the table to see if the data has been changed since the record was retrieved. There are several data types that Access is unable to check reliably (see article below). Simply adding a column of type timestamp changes this behaviour and instead, Access only checks to see if the rowversion has changed... which makes this check more reliable and also improves performance.
Oddly, this isn't really a timestamp at all - it's a rowversion, but in SQL Server 2008, which I am using rowversion isn't available via the GUI.
See https://technet.microsoft.com/en-us/library/bb188204%28v=sql.90%29.aspx.
Probably the leading cause of updatability problems in Office Access–linked tables is that Office Access is unable to verify whether data on the server matches what was last retrieved by the dynaset being updated. If Office Access cannot perform this verification, it assumes that the server row has been modified or deleted by another user and it aborts the update.
There are several types of data that Office Access is unable to check reliably for matching values. These include large object types, such as text, ntext, image, and the varchar(max), nvarchar(max), and varbinary(max) types introduced in SQL Server 2005. In addition, floating-point numeric types, such as real and float, are subject to rounding issues that can make comparisons imprecise, resulting in cancelled updates when the values haven't really changed. Office Access also has trouble updating tables containing bit columns that do not have a default value and that contain null values.
A quick and easy way to remedy these problems is to add a timestamp column to the table on SQL Server. The data in a timestamp column is completely unrelated to the date or time. Instead, it is a binary value that is guaranteed to be unique across the database and to increase automatically every time a new value is assigned to any column in the table. The ANSI standard term for this type of column is rowversion. This term is supported in SQL Server.
Office Access automatically detects when a table contains this type of column and uses it in the WHERE clause of all UPDATE and DELETE statements affecting that table. This is more efficient than verifying that all the other columns still have the same values they had when the dynaset was last refreshed.

Related

Access form Sql linked table write conflict

I have spent two days researching and try to fix my issue with access form edits. I understand that there may be similar questions out there, but none of the suggestions fixed my problem. Also, my situation might be slightly different.
I'm on Access 2017 and using an access split form that is tied to a linked table that is on sql server 2017. I have an add button that simply adds the record entered and moves to a new record. When I add a record to my form and then try to edit it in the datasheet view on my split form I get a write conflict error.
I've already validated that I have a primary key on my table and that there are no null bit fields.
The other thing to note is that this started happening after migrating from SQL server 2014 to sql server 2017.
One thing I read about and have yet to try because of the "drastic" change it entails is to set the compatibility level of my database to something lower like SQL 2014. This would be a last resort however and would only be to validate what the cause of the error might be.
I've tried everything on this page that is applicable to my situation: http://www.accessrepairnrecovery.com/blog/fix-ms-access-write-conflict-error
What else can I try to resolve this? I'm hoping someone out there has run into something similar.
First this question has been answered 100's of time on stack overflow.
Next up: Your link has nothing to do with using SQL server, so the suggests likely will not help.
The main causes (repeated over and over as solution) when using Access and SQL server are:
Ensure that all tables have a PK defined.
Ensure that any bit fields have a default setup on sql server (usually 0)
Ensure that each table has a timestamp field.
This is important, espeically if you have any floating or "real" data type columns. The Access up-sizing wizard, and the migration tool for Access both by default suggest and will add the timestamp field.
If you missing any of the above 3 issues (that have been repeated over and over for the last 18 years on near every article about using SQL server.
So, you will ensure that you checked above all 3 issues.
After any table changes, you will re-link the access client side.
You then need to test/check if you can change edit data using the linked table directly from access (in table view). if you can edit such data directly, then you are back to testing with your form. If the form still causes a write conflict, then suggests in the article you linked to will START to apply, but not until such time you address and ensure all 3 above steps are issues are dealt with.
The time stamp is often required for a sub form, and also when you have real/floating columns. Due to rounding errors in such computer numbers, then the compare between the two records fail. The adding of the timestamp column fixes this issue since access now does not have to do a field by field compare, but will use the timestamp column (not to be confused with a datetime column) to figure out if record has been changed. Thus adopting this feature even reduces the network chatter from client to server and allows access to determine if server record been changed without having to resort to a field by field compare.
I recently encountered the same error and it turned out to be that I had an active sort on the datasheet view. Once I removed the sort, voila, problem solved! (Nothing like shooting myself in the foot.)

If I update a SQL table Scheme. Do I have to update all users DBs linked tables?

I updated the SCHEMA of a live table in MySQL for use in my multi-user database. Each user has their own db and links to the production tables through ODBC.
I have been receiving a write error while trying to test my schema updates. I cannot find the core reason. I hypothesized that because the other users are in the production table but have not been relinked to update the table SCHEMA; That it is causing a conflicting write error on my relinked table.
I added a TINYINT with No NULLS and default value of 0
I double checked all datatypes for incompatibility & have tested the "non relinked" tables in a older version of the DB and confirmed it is working as intended with no errors
I expect/want to be able to edit records without a write error, but am hesitant to update the other users to the new table if it is currently having write errors
After changing the schema of a linked table, it's required to refresh the link on all Access databases connected to it.
You can do this on the ribbon through external data -> linked table manager.
Unfortunately, either all users that have a database need to do this manually, unless you automate the task on startup through vba.
You have two separate issues. To "see" new columns, then yes, you must re-link the tables.
(so above is separate question and separate issue). You thus as a general rule can add new columns to the database (even while in use). However, the client side linked tables will not see the new columns until such time you re-link. This approach (adding new columns, but not yet re-linked from Access) is certainly ok and fine - the only downside is end users can't see nor use the new columns until such time you link. From a developer point of view, this good - since your users will not see nor find new columns until such time you roll out a new front end to each work station.
Ok, now problem and issue number two.
As for adding a new column, then re-linking, and THEN having some issue is really a separate issue. In most cases, if you attempting to use a tiny int as a Boolean (and I think that is your case), then you need to ensure several things:
Do not allow nulls (you seem to have this ok).
Make sure you set a default of 0 (server side) for this column. (you might have not allowed nulls, but without a default, then Access likely will still complain. And this default is important during creating time - since the new column needs to be "filled" with zeros.
Make sure the table has a PK defined.
Consider adding a row version column (I think mySQL has these, not sure but they can help immensely).

MS access error with mysql

I was working on an application that uses ms access 2010 and oracle. Now I am working on using my sql 5.7 instead of oracle.
But the code in ms access contains recordset.edit and then 2 set statements followed by recordset.update.
recordset.edit
recordset.Fields(22).value=1
recordset.update
This gives run time error 3197. You and another user are attempting to change the same data at same time.
I have tried to match all data types. But nothing seems to work. Still i get same error.
Appreciate your help. Thanks in advance
This “other” user message is often misleading, and in fact another user has not updated the record.
Two things to check for:
If some sql update, or recordset code “may” update the current record you are working on, then force a disk write and thus no pending updates exist:
Eg:
If me.Dirty = True then me.Dirty = false.
YOUR code here such as above is now called/run
The 2nd common issue is null bit columns. These often confuse access, and thus you need to MAKE SURE at the SERVER level you have a default set for such columns (a value of 0 for sql server – not sure if same for MySQL). So this is a MUST check issue.
Next up:
Make sure the table in question has a PK, and you should add a row version (timestamp). This type of column is NOT to be confused with a date time, or a column to hold current time – it is a row version column. So add a timestamp column, make sure PK column exists, and make sure any bit (true/false) column in the table has a default. If existing bit columns have null values, then run update query to set them all false (0).
After you make the table changes (if required), then re-link all your access tables.
The above should cover 99% of the cases when you get that “other” user message when in fact you are sure it is not another user.

Why don't date functions work as defaults in MS Access used with MySQL

I am converting a Large MS Access 2010 application to act as a front end to MySQL 5.5 database, via the v5.1 ODBC Connector, and I am experiencing a strange problem when inserting new records with bound data forms.
In a data-entry form, if the default value of a date field is set in the properties of the control as a constant (such as #04-01-2014#) the new record is created in MySQL successfully, and after saving, all fields are visible in their associated bound fields. But if the default value is defined in the Access control as a function (example: =Date()) then although the MySQL row is created successfully, ODBC fails to find the new row and Access displays all values as #DELETED. Refresh and/or requery commands are not helpful. This is nothing to do with the well known issue of -- must have a primary key and a datestamp in MySQL. All of these safeguards are in place, and as stated, it does work without FE defaults.
No defaults are being set in the MySQL backend, and it makes no difference whether or not Nulls are allowed. Data type used in the backend is DateTime. If I do set defaults in the BE and none in the FE, everything is fine. But that way, the user DOES NOT SEE THE DEFAULTS in the data entry form... an unacceptable situation.
I have also tested both ODBC v5.2, and MySQL 5.6 with exactly the same results.
A solution that seems to work (so far) is to set all defaults in code, in the form.beforeUpdate event. Something like this:
form_beforeUpdate()
if me.newrecord then
field1.value = date()
field2.value = fOtherDate()
'etc
end if
'other code
exit sub
I could insert all new records with unbound forms and passthrough queries. But with 75,000 lines of code, that is a very big job
My question is - why do I need these "workarounds"? Isn't the whole purpose of ODBC to allow fairly normal operation? What is it about simple functions that "breaks it"? What other "ordinary" Access methods will break it? If I don't understand why it didn't work I can't be sure it is properly fixed.
Has anyone else had any experience with this SPECIFIC issue? I could not find any reference to it elsewhere. Thank you for your time.

Access 2010 Write Conflicts with SQL Server 2005 Backend

I recently upsized an Access 2010 database to use SQL 2005 as the back end database using SSMA for Access. The migration was completed without problems but now users are getting a write conflict anytime they try to change something, even text in a description field. SSMA inserted a timestamp field in each table, which I thought would prevent the write conflicts. Is there something I need to do to Access to force it to use the timestamp field?
The error is:
"This record has been changed by another user since you started editing it. If you save the record, you will overwrite the changes the other user made."
While researching this I've tried other approaches such as setting BIT or REAL fields to NOT NULL and inserting default values. This made no change to the issue. The write conflict even happens when updating an Nvarchar(MAX) field. I changed that field to Nvarchar(255) but the error still occurred.
I should point out that Access is using a workgroup mdw file for security.
Can anyone help point me in the correct direction? I've done several of these migrations before but never had this problem.
Thanks,
Joe
Ensure that that bit columns don't allow null. Ensure such bit columns have default set of false (0). Ensure All tables have a timestamp. Ensure that all tables have a have a primary key.