Check whether any field has change in Trigger

What you'd need to do is something like the following:

mapFieldMapNew = Schema.getGlobalDescribe().get(sObjectName__c').getDescribe().Fields.getMap();
String key = ' '; 
String value = ' '; 
mapLabelToFieldsObj = new Map<String,String>();

for(String s : mapFieldMapNew.keySet()) { 
   key = mapFieldMapNew.get(s).getDescribe().getLabel(); 
   value = mapFieldMapNew.get(s).getDescribe().getName();
   if(mapFieldMapNew.get(s).getDescribe().isUpdateable()) mapLabelToFieldsObj.put(key, value); 
}

That would give you a map of all the fields in the sObject that are updatable which you could simply convert to a list or set of field names if you wanted to. You could then use those fields to test to see if anything has changed between trigger.new and trigger.old on those fields.

Although it's implicit, don't forget that you also have the isCreatable attribute for a describe call and could potentially have new records that you'd also want to test for which could exist in trigger.new, but not in trigger.old if your trigger included an afterInsert section.

EDIT

I should add that its also going to be important to know what Type of field each one is. You can't go around and compare certain types of fields with the assumption of an equality either being true or false. You also may need to have try catch blocks to prevent exceptions from being thrown where data exists in say trigger.new, but not trigger.old which could cause a null pointer exception when you try to access it. Those are things you'll want to set up in advance for the field type you're going to compare.


You could do a quick comparison with a Set operation.

You could simply go:

Set<sObject> oldRecordSet = new Set<sObject>(Trigger.Old.deepClone(true, true, true));

oldRecordSet.removeAll(Trigger.New);
Integer numberOfChanges = oldRecordSet.size();

If the number is 0, there were no changes. Otherwise, you have the number of changes.

If there were changes, you can then get the Ids of the records that did change like this:

Set<Id> changedRecordIdSet = (new Map<Id, sObject>(new List<sObject>(oldRecordSet))).keySet();

I haven't tested it yet, but I believe this will work.

Edit

There's one issue with doing this approach. It will always return Trigger.New if you think about it. Even if you checked all fields that could be editable, there are always fields that will be edited, like the LastModified date.

Tags:

Apex

Trigger