With my customer we have moved from a central Software Update Policy model, using ZeroDayPatch, to avoid replication issues (we had some malfunctioning policies upon replication that caused a less than optimal compliance level).
It works very well, but we have some issues with some bulletins for which creating a policy was proving very difficult. The symptom is that when you create a new policy for the impacted bulletins, loading the policy will cause a general error (when you get the database error message). And on the "Home > Patch Management > Bulletin and Updates" grid view the bulletin will not show any policy associated even after a refresh.
To cut a long story short the problem lies in replication, as you could have guessed form the environment. The issue here is that revised updates are handled on the parent server and replicated down the hierarchy, however the update that was revised (the previous version), which is deleted on the parent, is not deleted on the child (in RM_ResourcePatch_Software_Update)!
Luckily, this non deletion of revised update resources can be detected because the resources will not have a matching entry in Inv_Software_Update. So we can map the RM_ResourcePatch_Software_Update to Inv_Software_Update to find out the resources to delete.
However it's not so simple to craft the query for our solution - the sample below would return a lot of result that are legitimate and to absolutely not clean up:
/* _NOT_WORKING_SQL_ */ select * from RM_ResourcePatch_Software_Update r left join Inv_Software_Update u on r.Guid = u._ResourceGuid and r.file = u.file where u.guid is null
I won't detail out why this doesn't work, rather we'll switch the query around to get some interesting results. Given the above can't work what we'll need to do is to get a list of all valid update resources, and exclude them from the full content of the update resource table, as shown here:
/* Detection SQL for all invalid entries */ select b.name, u.[name], u.guid from RM_ResourcePatch_Software_Update u left join ResourceAssociation ra on u.Guid = ra.ChildResourceGuid left join RM_ResourceSoftware_Bulletin b on ra.parentresourceguid = b.guid where u.Guid not in ( select r.Guid from RM_ResourcePatch_Software_Update r join Inv_Software_Update u on r.Guid = u._ResourceGuid )
With this you can now have a (very long) list of orphaned entries (you'll notice that many of the entries if not all are not showing a bulletin name) that can be used to clean off the orphaned resources.
Now, I won't delve into the deletion process, but you can always try to insert the guids into ItemToDelete and let that work the clean up process if possible.
If not you'll have to clean the resource table and make sure no references are left in the ResourceAssociation and ItemReference tables.
Note that the issue is solved for now on this customer, but we'll probably need to run some SQL task to make sure that deleted entries from the parent are ot left over and creating problems on the child SMP's.