Today I had an issue where I had deleted a number of records from CRM during my loads of testing through Scribe. After deleting these records, CRM updated those records to have a deletestatecode = 2. Therefore, every subsequent scribe job would no longer work properly as the address still existed in the database. Those of you used to CRM 3.0, there used to be a MSCRMDeletionService you could restart in your running services and it would force the job to run through all your records. That is now wrapped in the Async Service of CRM 4.0 which you can restart. For those of you who don't/can't restart that service for any reason, try this here:
UPDATE dbo.ScaleGroupOrganizationMaintenanceJobs SET
NextRunTime = getdate() -- Now
WHERE OperationType = 14 -- Deletion Service
This was found on an old archive site, posted by Aaron Elder. Hope this helps others find it. Be patient. I fumed for a few
minutes thinking it wasn't working but just give it some time. ;)
When all else fails.....
There are other ways going directly to the database level, but I cannot stress how bad of an idea that is and how much it should never be done. Exhaust all other options CRM provides you before going to the database level and modifying it by hand. 'Because it would be faster' should never be a good enough excuse!! If you have no other options of using CRM to it's full abilities and must do it by hand, something went horribly wrong and needs to be re-evaluated immediately after you clean up your data.
you're still reading....*sigh* ok but I warned you.
CRM gurus correct me if I'm wrong, but from the understanding I have at this moment, every entity in CRM has two tables:
- [YourEntity]base - table that holds all the default out of the box attributes of your entity
- [YourEntity]extensionbase - table that holds all your 'new_' custom attributes for your entity
So if you have a 'Contact' with a 'new_foo' attribute and someone adds a new 'Contact' to your CRM instance,
- 1 row added to your 'Contactbase' table - holds address1_line1, name, firstname, etc (all defaults)
- 1 row added to your 'Contactextensionbase' table - holds new_foo (all custom)
The BOTH have the same ContactID because they ARE the same contact. So if you have to delete at the database level you MUST delete from the extensionbase table first and foremost. The smartest thing to do is to first find out exactly which contacts you need to delete. Whether its on IDs or a certain field state, get a select statement as correct and accurate as possible. Once you have that select, I like to make a temp table of those records but this is purely optional. The reason I like to do this is because sometimes the field I care to do my search on is a 'new_' attribute. Where 'new_foo' = null. But if I run my delete query on extensionbase where 'new_foo' = null, I just shot off my own foot. The reason? I just deleted all the rows who had any knowledge that 'new_foo' existed. How do I know what rows I just deleted to now clear out the base table? With a temp table, I can capture all that data and include a 'contactid' so I never am without a reference of what fields need to be deleted.
As always, BACKUP before attempting this. Run your delete on extensionbase. Write down the number deleted. Run your delete on base. Match number deleted. If it doesn't match, Panic. Restore you database and refine your search until those numbers match. Re-evaluate your process and NEVER DO IT AGAIN!