Cannot edit one record on linked table write conflict - sql-server

We have a linked table in our Access 2010 database, the backend is SQL Server 2012, via an ODBC connection. The table is indexed (unique, non clustered) on a single field, the record's identifier.
The issue is that the odd record throws a 'write conflict - record changed by another user' type error when it is edited through the Access front end, but can be edited directly in SQL. Other records are fine. It's not the same record each day. The whole situation is a complete mystery to me so here are all the fact, maybe someone can make a coherent picture out of this.
The error message takes two different forms, depending how the edit is attempted. The normal functioning of the front end does it by opening a DAO recordset with just the one record, doing a bunch of edits on different fields, then closing the recordset and setting all object variables back to nothing. That produces first the "Write Conflict - This record has been changed by another user since you started editing it." error, with "Drop changes" or "Copy To Clipboard" as the options." It is then followed up with error 3197 "The Microsoft Access database engine stopped the process because you and another user attempted to change the same data at the same time."
If I just open the table in Access and manually try to change the record, I get the write conflict version of the error only. (Needless to say, I have confirmed that no other users are in the table at all, let alone the record.)
I can edit the row in SQL, and I can edit the row using a query in Access (via query design).
The data in the table is built each morning, and each day it seems to be a different record or two that is affected. It has only gone on for a few weeks, in a setup that has been running fine for about 6 months with no changes that could account for this (at least, that I can think of). The data build truncates the table and inserts all the records from scratch, and then rebuilds the index.
Here are some things I've tried:
Decompiling the database, compact and repair, relinking the table.
Linking the table into a brand new database that only has that one table in it.
Rebuilding the index.
Deleting the row and re-inserting it
Rebooting the SQL server (that was due to something else, but the problem still continued afterward.)
Opening the front end on a different computer.
Any help would be much appreciated!

Related

Insert Data From Access Database to SQL Server

Desired result and why:
I have a lot of old Access databases that we are trying to get to SQL Server, and I'm essentially trying to make the Access DB the "middleman" so our old programs can still read/write to them but the information will also be saved in SQL Server. We need the middleman because of how interconnected these tables are through various programs we are rewriting in modern languages. Once we rewrite all of them we will cut the cord and live in SQL Server, but this will take a lot of time.
What I've tried:
We tried creating a linked table to SQL Server and renaming it so it would take the place of the original table. After doing this the table stopped receiving data so we quickly reverted back.
In order to investigate this I created Table B which is just another linked table to SQL Server, and then tried using the After Insert macro on Table A to send any new rows to the linked table but nothing happens. If I manually add a record to Table B it carries over to SQL Server just fine, but I can't get Table A to send data to Table B. I created Table C that is just a local access table and if I manually add a record to Table A it does show up in Table C. No errors at all, it just doesn't do what I need it to do.
I'm lost on how to accomplish this and open to any help or suggestions on how to move forward with this. One thing to note though, is that most of the access databases I have are not using forms at all which is I'm trying to take the macro route instead of any VBA. I need these to trigger without any interaction from the user.
You should use the tool dedicated to this task:
SQL Server Migration Assistant for Access (AccessToSQL)
Ok, there are from comments some new and signficant moving parts here.
For example, data is to be migrated to sql server. As noted, EVEN in access land, all and every table needs and should have a PK for the "basic" data base operations. While it is possible to do some work, and say some importing of data, the instant one wants some forms, VBA code and starts to build a working applcation? Then all tables should have a PK.
And of course if you moved the data to sql server, then it not going to make a lot of sense to have OTHER applcations attempt to modify the linked tables in access, since the data is not in Access anymore!!! Those other sources in theory should thus also hit sql server, and not attempt to use what amounts to a link on a linked table.
However, it does depend. For example, if you use vb.net code and say open a access database, you CAN in fact have that vb.net code open a access table, and in fact it can be a linked table. (however, it would make a WHOLE lot more sense for the vb.net code to open and hit sql server - introduction of a link on a link is going to be problematic.
However, in testing, I have found that say vb.net can open a access table, and even if it is a link, then access will translate though the jet engine (the access data engine), and you can do this.
However, data macros and table triggers on existing access tables? They might work on linked tables, but you of course need to ensure that the linked table does allow edits, and allows inserts. Only AFTER one has verified that you can click on a linked table to sql server - can edit, and then add should one mess around with data macros and triggers on say local tables.
it also depends on what the new software tools and platform is being used here.
But, from a basic database point of view - and general data mangement?
All code, and designs should assume, and be designed around the assumption that each row of data has a PK. This is not always possible, but is a RARE use case.
Practical data management - and use of a database should from both table designs, and from workflow designs, and from a developer point of view assume the concept of a PK row id. Without such assumptions, then you not in the software industry anymore - but in a hack field, and one that will result in great future difficulty when attempting to build work flows and build general information systems.
So, with above in mind: Your table B - it has to work as a valid sql server table.
The sql server table(s). They need a PK, and after linking to sql server, you can open up the linked table in access. Test if edits work, test if adding works, and even perhaps test if delete works. Only AFTER such time, do you now want to start testing any code or other operations from the Access client side.
Introduction of using a linked table from another application? That is a foggy area, but I can confirm for example that say .net oleDB provider will and can open a access database and use + consume even linked tables.
You also don't mention if you using sql logon, or windows auth for the sql server linked tables. But if you using sql logons, then when linking a table, you see this check box - and you want to ensure you selected this when linking the table(s) in question:
Note that you ONLY get this prompt on the first time create of the table link - additional use of the linked table manager (such as re-fresh links) does not offer this prompt. If you don't select the save password option, then you often see a sql logon prompt when you attempt to open a linked table in access.

To change the IDENTITY property of a column error in EF Core DB

I started getting this message when trying to add a new column to a database table. I did not try to make any change to the key column in the DB.
To change the IDENTITY property of a column, the column needs to be dropped and recreated.
So working through various potential solutions online, I have been trying to drop the table and replace it etc. without any luck. When I run Update-Database in PMC I get the same error so nothing can be dropped, nothing can be added to the DB. Its completely blocked and I have no idea why because I did not change anything fundamental in the DB, I just added a normal int column to the table and tried to migrate an update.
So then, I saw info online saying that I should delete the table and update the database, and EF core would replace the table to get the DB back in sync. I right-clicked the table in VS SQL Server Object Explorer and deleted it. But when I add the migration and run Update-Database, I again get the error:
To change the IDENTITY property of a column, the column needs to be dropped and recreated.
This is not yet in production, so I don't care about the data loss from deleting my table, but its completely blocking me. How can I get my Database-Update to run again so I can get my table back and not see this error?
I have no idea what caused this issue. At this point I'm thinking I should create a brand new database in Azure for my solution and recreate tables one by one, but that will take days/weeks and I don't know if it will get rid of this issue.
Has anyone come across this issue and do you know if recreating my DB from scratch will solve the problem or does it usually originate somewhere that a complete DB recreation wont help?
I fixed it! Sometimes you just need to write it down to come back with a fresh approach!
By using ''Update-Database -Migration [migration name]'', I was able to try every migration one by one, working back from the most recent. By doing this I identified that the problem was with a specific migration 4 or 5 migrations back. Thankfully I always keep migrations small. I then used Remove-Migration to remove them one by one, back to the last good one. This allowed me to follow the steps I found online and was trying yesterday, to create a new table. But I had another error about duplicate column names, so I needed to create my new table with no columns, and delete some columns from the model of the old table before I could drop the offending table (Still dont know why it stopped working). Then I added the old table model to the new one to get my columns back and renamed the new table to match the old one. Working fine now. There was also a bit of commenting and uncommenting needed to get the build working as I switched the tables.

SQL Server migrate new data into old schema

I have converted MS Access tables and queries to SQL Server tables and views and linked them back to Access. While I was doing this migration, people were using the old Access frontend not linked to SQL Server. Now, the data that I have in SQL Server is the old data when I started the migration. I have created tables, indexes, queries etc in my SQL Server which uses the old data.
Now, I want to deploy the SQL database and link it to Access. Is there a way for me to delete my old data and migrate the new data to SQL Server database while preserving all the schema?
Edit 1:
If you did the migration using SSMA (Sql migration assistant for Access) then you can simply re-run that saved project.
The first time you run SSMA, it will create the data tables on sql server, and then transfer the data.
However, you can open that same SSMA project again, and re-run it, will give you the option to delete the data on SQL server, and send up the existing Access data again.
One of the “really” great features of SSMA is it lets you re-send the data. So you can slice and dice, and try the migration MANY MANY times.
Once you get the migration going the way you want, you migrate the data. You then work on getting your front end to work with sql server. During this time, no doubt users are still using the older system (non sql server).
For example, SSMA allows you to add a PK to each table (if it does not have one). I often found a “few” tables such as for driving combo boxes etc. does not (did not) have a PK for that table that say drives a combo box. So during the migration, you want to let SSMA create the PK for you. You can do this manually after the migration, but then you need to write down some “cheat” notes, since as you point out, you going to have to do the migration again later on.
So, if you make any “manual” changes to the data structures, then you want to “save” those changes in the event that you migrate again. The beauty of this, is WHEN you in the table design mode (sql server), you can right click, and choose “script” changes. So if you make say 10 or more changes to each table, you can save your changes into a sql script. So now you can migrate, and then run those scripts.
Now, after the migration, you get to work making this front end work with SQL server. During this time no doubt users are STILL working on the old system (access back end).
Once your new front end is working fine with sql server, then you pick a day for the new roll out. You after work, or during down time, re-run the SSMA project you saved. The result is now SQL server has the most up to date data. And then you are now able to roll out and deploy out the new front end that is linked to SQL server.
As noted, while SSMA can migrate Access queries, I VERY strong recommend you don’t do this. Just migrate the data, and link the front end tables to sql server. At this point, 99% of your Access appcation will work as before. You “may” have to change the VBA open recordset commands (to add dbOpenDynaset, and dbSeeChageesto that openRecordSet command (but that is a global search and replace – not much time at all).
So you likely have lots of code like this:
Set rst = CurrentDb.OpenRecordset(strSQL)
And you need to change above to:
Set rst = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset, dbSeeChanges)
The above will thus allow 99% of your VBA reocrdset code to work as before without changes.
The only “common” got ya, is with a Access back end, the autonumber ID is generated INSTANT as a you dirty a form, or dirtry (add too) a record. This allows code to grab the auto number PK right away.
So such old code as:
Set rstRecords = CurrentDb.OpenRecordset("tblmain")
rstRecords.AddNew
' lots of some "code" here follows
lngPK = rst!ID
In above, note how my VBA code grabs the PK auto number.
In sql server, you cannot grab that PK until AFTER you force the record save. And DAO has a VERY nasty issue is that after you issue a update (during add only – I repeat during adding reocrds only!!!), then the record pointer jumps off the current record. This DOES NOT occur when you using DAO recordsets to update a existing record (again: only for new reocdors).
So, so above code now becomes:
Set rstRecords = CurrentDb.OpenRecordset("tblmain")
rstRecords.AddNew
' code can go here to add data, or set values to the reocord
rstRecords.Update
rstRecords.Bookmark = rstRecords.LastModified
lngNext = rstRecords!ID
rstRecords.Close
So, for code that grabs the autonumber PK right away, we have to do two things:
Force a record write (update)
And then after the update, re-positon the record pointer. (you ONLY need this re-postion when adding – not edits, but I often do this anyway). This re-position issue is perhaps my LARGEST pain of using DAO (ADO does not require this re-position).
So your code add/sets the fields etc. in that reocrdset do NOT have to be changes. So leave that code that does whatever the heck the code did before.
Now issue the update, AND THEN GRAB the autonumber PK.
So above should cover 99% of your VBA code you have to change. Even in a rather large project, the above issue will only occur in a few places. (I find that I can search for “.add” in the code base, and rather fast determine if code is grabbing the autonumber PK before the “.update” command is issued.
The same goes for forms. When a user starts typing, the form becomes “dirty”. With Access back end, the autonumber PK can be grabbed by code, but with sql server back end, you have to issue a record save in the form, and THEN grab the PK ID.
So, you add this one line:
If me.Dirty = True then me.Dirty = false
lngID = me!id
So you added the one line to force a record save (me.Dirty = false).
And again I tend to find even with say 150 forms, only 1 or 2 will do this “grabbing” of PK id before the forms record has been saved. So this “lack” of autonumber being able to grabbed for new records will occur for both forms, and VBA reocordset code. Few forms do grab the PK autonumber ID, but some do need this (say to add child records). However, existing forms + sub forms do NOT have this issue, since access ALWAYS issues a record save when the focus jumps from the main for to any sub form.
Anyway, once you get the new front end working (and of course one linked the front end using the same table names as before).
If I recall, SSMA tends to put “dbo” in front of the Access table link names – you don’t want that. The dbo schema on sql server side is the default, and again that should not pose any issues or problems.
So yes, SSMA allows you to re-run the migration, and it allows you to delete your data on SQL server during that re-migration. You not need to delete the old data, SSMA can do this for you.

Adding a new column in MS SQL Server Management Studio leads to database freezing

I try to add a nullable bit column (without a default value) in a table with 39 records in it. On saving the studio freezes and isn't able to execute the desired change. The connected application cant't be executed either, I get a timeout there. I tried to add the column via user interface and also via a SQL command, with no success in both ways.
The table I'd like to change has several related tables. In operation there is no writing access on the table, but many reading accesses. After rebooting the server I was able to add the column. The update process lasted unusually long anyway. Updating the same table on the same server in another, identical database which is used only from a few users worked fine (within a few seconds). Adding the column in the local database also worked without problems.
Unfortunately I couldn't find a way to solve my problem and I can't reboot the server every time I'd like to modify my table.
Hope you can help me.

Message: This row was successfully committed to the database. However, a problem occurred

I have a table in SQL Server 2005 whose primary key is an identity column (increment 1), and I also have a default value set for one of the other columns.
When I open the table in SQL Server Management Studio and type in a new record into the table, the inserted values are not displayed, and I get the following message on save:
However, if the table has either an identity column, or one or more columns with a default value specified, the inserted value(s) will be displayed in the table after a save. And can be edited.
I frequently create test data in ssms this way and this issue makes it cumbersome to do some things I would like to.
Is there any way around this?
Right click on it and say Execute SQL...it should not display it(error)..its just sql server way of doing things..since it inserts the identity column later..You should not add records in that way in the first place.
You should not add records to a database that way! It can have unfortunate side effects (especially on large tables) as you have discovered.
Records for lookup tables should be added through rerunable scripts. Those scripts should in source control. This makes them easy to promote from dev to Qa to staging to prod.
Test records should also be done in scripts (including scripts to remove the test records) so that you can run thenm on other environments as well as being able to delete and recreate them if some process you are testing went bad. These too should eb in source control (as should all database changes which also should not be done through the GUI).

Resources