Error 2501 while trying to delete a record - sql-server-2008

I have an Access database front-end and I'm trying to put a button on a form to delete the current record. I used the following VBA code to delete the record:
If Me.NewRecord Then
Me.Undo
Exit Sub
End If
DoCmd.RunCommand acCmdDeleteRecord
Me.Requery
Me.Refresh
When I run this on records that I inserted into the database with the form, It returns Run-time error '2501' on the DoCmd. However, if I run it on a record that had already existed in the database then the code completes as intended.
Additionally, no one else is accessing this database table yet and I only had the one form open.
When I went to delete them from the linked table manually in access I got the same error but I was able to delete them from the database using SQL Server Management Studio.
What would cause this to happen?
EDIT
I did some more investigating and found that I am unable to edit the new records in in the base table using access either. I get an error about the records being changed by another user.

Other than the recommendation to have a timestamp field in the table (SSMA assistant adds this to all tables when you use it to upsize from Access, and it's definitely something I'd recommend), I have some criticism of your code. I'd write it this way:
If Me.NewRecord Then
Me.Undo
Else
DoCmd.RunCommand acCmdDeleteRecord
Me.Requery
End If
The refresh is redundant after a requery, as you already have the most recent data.
Using Exit Sub is helpful for guard clauses on things that aren't mutually exclusive, but in this case you have an either/or -- either your going to delete an existing record or undo a new record. That can be handled within a single If/Then/Else block and then you have a single exit point for your subroutine, which is very helpful in case the code grows more complex in the future.

This is not the answer to your specific problem, but regarding the question title of getting Error 2501 while trying to delete a record, another situation where that happens is this:
You try to delete a row in one table that would orphan rows in another
table (because the two tables are linked via a foreign key). SQL
Server rejects the deletion and Access returns that vague 2501 error
code.
In my case, I solved the issue by dropping and recreating each foreign key with ON DELETE CASCADE so that when a row in the "main" table is deleted via Access, SQL Server automatically deletes the corresponding rows in the each "detail" table.
See these questions for more detail on cascade delete:
Good explanation of cascade (ON DELETE/UPDATE) behavior
How do I use cascade delete with SQL Server?

Related

Access 2010 error when moving focus to subform or acSaveRecord

So I have a Form in Acess 2010 with two subforms to manage one-to-many relationship, for Projects and Tasks, they are bound to two linked tables on SQL Server so whenever I load a project, the tasks are listed on the subform.
Lately I have been encountered an error on primary key violation whenever I move from a field on the main form to any area of the subforms. This tells me that the primary form is trying to save whatever it was loaded, but instead of UPDATE, it's trying to INSERT.
There is no code or event that I can see (like before or after update) that may do that specific command. There is a Save button on the form, this button is using DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70 and it produces the same error.
Is there a way to indicate Access to use UPDATE instead of INSERT?
I have been looking all around but don't seem to find any related fix.
Thanks to everyone!
EDIT: I have tried removing the primary key on the linked table and the error goes away, but as suspected, it is inserting duplicates every time I move to a different record or click on the subform. So if anyone have a clue on the record navigation behavior and how to configure it, I would appreciate very much!
If there are triggers on the SQL tables, it may be the trigger that is calling the INSERT statement rather than the front end.

Microsoft Access: warning about duplicates when record was created by data macro

The changes you requested to the table were not successful because they would create duplicate values in the index, primary key, or relationship.
This is the error message I receive when I am halfway through keying in data into my subform. My subform's source is a Query that joins two Tables on a one-to-one parent-child relationship. I assume the following happens when I key in data:
I have an After Insert data macro that creates a row in the child table.
The data macro fires and a row is created in the child table with the corresponding foreign key.
Microsoft Access is not aware that I have created that row in the child table.
When I key in data that belongs to the child table in the subform, it automatically tries to add in a new row into the child table. This fails because a row already exists with the same foreign key.
Is there any way I can bypass this behaviour? Can I bridge the link between the parent and child table the moment the data macro is fired? I can't forgo the After Insert data macro because it contains some biz logic that helps identify which child table to insert into, and it's important that the row is created in the child table as soon as data is filled in the subform and not only when the child table's fields are touched in the subform.
Many thanks!
EDIT: I tried working around this by running Me.Requery in the After Insert macro of the subform. Seems to work fine for a single record, but with a batch copy-paste the error Operation not supported in transactions. occurs.
EDIT 2: I even found this forum thread that says that it's kinda impossible to Requery after a transaction. I'm kinda sure there should be a way around this because it seems kinda user-unfriendly...
I generally recommend against using timers but this is a case where you could use one. On the AfterInsert set the form's TimerInterval at something like 500. Then put your Me.Requery code on the Timer event and also set the TimerInterval back to 0.
After AfterInsert event should set the TimerInterval back to 500 which will prevent the timer from firing until all records have been pasted in.
I see you are using Macros. I don't know if you can use the timer in Macros or not. I don't use macros at all and I recommend learning VBA instead of using them.
Private Sub Form_AfterInsert()
Me.TimerInterval = 500
End Sub
Private Sub Form_Timer()
Me.Requery
Me.TimerInterval = 0
End Sub

Access Can't delete records due to lock violations

We have been using a Delete command on Access 2003 with xp machine from past few years and it was working good until we upgraded our systems to Access 2010 and Windows 7.
Please see the error below. No sure what i was missing. I tried creating a new link oracle table, but it didn't work.
I just ran into the same lock error when trying to update a linked SQL Server table via MS Access 2010.
This may no longer be a problem for you since the thread is so old, but hopefully it makes it easier on someone else in the future.
I was able to fix it by changing the ID field in SQL Server from a bigint to an int.
You may also want to make sure that "Default record locking" is set to "No locks" in Access Options --> Client Settings --> Advanced
DefaultRecordLocking http://www.tmetrics.net/support/patrick/stackoverflow/defaultrecordlocking.jpg
I had this error with a linked table that had a primary key and a unique key. When linking the table, Access assumed the unique key was the primary key.
By temporarily disabling or deleting the unique key and refreshing the ling using Linked Table Manager" the problem was resolved.
It appears that the 332 records it can't delete are locked, perhaps by some other process? Is there a stagnant process running somewhere that is holding a lock on those records?
I had a similar problem... Could delete records manually, but through query was getting that message.
Even though I was deleting records in the "many" table in a one-to-many relationship, a "key violation" message kept appearing.
I edited the relationship to ADD Cascade Update and Cascade Delete, and the problem went away.
I am having this problem. I have an Access front-end to an Oracle database. I am trying to delete records from a linked table. I have not found a solution anywhere on the internet. Here is my "solution".
I converted from DoCmd.RunSQL to DBS.Execute to run my Delete query. That got rid of the error message. But not all records were being deleted still. So now I execute the delete query in a loop.
recCount = DLookup("count(*)", "my_table")
Do While recCount > 0
DBS.Execute "DELETE * FROM my_table", dbSeeChanges
recCount = DLookup("count(*)", "prod_nmpsia_premiums")
Loop
Sometimes it only takes one pass. Other times it takes a few.
I know it's a kludge. But it works.
I was running into this same issue using Access 2016 and an Oracle database. I could append to the Oracle tables just fine, but when I ran the delete query to remove those same records, it would delete some records and say others were locked. If I looped the query enough times it would eventually erase all the records.
The solution I found was in the Access delete query, I set the 'Use Transactions' property to 'No' and it started working fine without any record locks. I don't know if this is a perfect solution, but it is working in my case.
--Update--
The above solution worked for some of my queries but then I still ran into the issue on other queries. So it helped in some cases but didn't work completely.
What does seem to be working now is that I stored a Procedure in Oracle that would delete the data I needed to delete and I am calling that procedure from Access.

table locked or in use when calling RunSQL

I have some code which re-arranges some items on a form, but only one SQL query. All my tables aren't locked before the code runs but for some reason I get an error when running:
DoCmd.RunSQL ("Select * Into MasterTable From Year07 Where 'ClassName' = '7A'")
Error:
The database engine could not lock table because it is already in use by another person or process. (Error 3211) To complete this operation, a table currently in use by another user must be locked. Wait for the other user to finish working with the table, and then try the operation again.
Any ideas what I can do to stop the table being locked?
Is MasterTable included in your form's Record Source? If so, you can't replace it, or modify its structure, while the form is open.
Apart from the table lock issue, there is a logic error in the SELECT statement.
Where 'ClassName' = '7A'
The string, ClassName, will never be equal to the string, 7A. Therefore your SELECT can never return any records. If ClassName is the name of a field in your Year07 table, discard the quotes which surround the field name.
Where ClassName = '7A'
I'm guessing, but if you're using a form that is bound to MasterTable, you can't run a query to replace it with a new MasterTable while you've got it open in the form.
I would suggest that you get rid of the MakeTable query (SELECT INTO) and instead use a plain append query (INSERT). You'll want to clean out the old data before appending the new, though.
Basically, a MakeTable query is, in my opinion, something that does not belong in a production app, and any process that you've automated with a MakeTable query should be replaced instead with a persistent temp table that is cleared before the new data is appended to it.
I have seen this when you re-open a database after Access has crashed. Typically for me a reboot has fixed this.
What version of MSAccess? Not sure about newer ones, but for Access 2003 and previous, if you were sure nobody was in the database, you could clear up locks after a crash by deleting the .ldb file.

How do I overcome / work around this difference between local and linked Access Tables

Ok. Quick background:
MS Access 2003 with 2003/2003 format MDB file upgraded from Access 97.
For the purposes of this example, there are two tables.
Table 1
Asset
ID - (text 20)
ParentID - (text 20)
Other fields
AssetRels
ID - (text 20)
When a record is added to Asset, the ID is added to AssetRels.
From Asset.ID to AssetRels.ID there is a relationship that exists that enforces referential integrity with cascade update and cascade delete.
From AssetRels.ID to Asset.ParentID there is a relationship that enforces referential integrity with cascade update only.
I have 2 records in Asset
VACU0703200, NULL
VACU0703250, VACU0703200
In the data DB, I can go into the table and change VACU0703200 to VACU0704500 and the changes propogate as expected.
If I open the front end DB that links to the data DB, and try the same change (in the table directly) I get "Could not update; currently locked" (no, nothing about 'another session', that's the whole error message)
Both databases are set to "no lock" for the "default record locking"
Obviously, there is some difference in row/page/table level locks that is preventing the cascade update from working.
Does anyone know of some property settings that I can use somewhere to stop this error?
I would prefer not to have to remove the relationship, but otherwise I might have to, and handle it in code.
Edit: Cause is that the table contains a Memo field. Apparently via the linked table, having the Memo field overflow the 4K row size escalates to a table lock. which in turn triggers the problem.
Solution (hackish) is to prevent edits to the ID field on the form, and add a new form to rename. Save changes before opening the new form, and performing the update via an update query works.
I don't see why moving to the front end and editing this from a linked table should make any difference. I would however delete the table links, and then RE link. Often sometimes some properties are set up and read a time of linking, if you go to the back end database and change some of the table properties, often it's a very good idea to RE link the tables.
As a general rule, you more often have to do the above when you add new columns with linked tables to SQL server. However, I would suggest you delete your linked tables in the front end, and try RE linking, this should fix this problem.
Solution (hackish) is to prevent edits to the ID field on the form, and add a new form to rename. Save changes before opening the new form, and performing the update via an update query works.
The cause is a table lock escalation that occurs when the text overflows the 4K table row limit.