I need to retrieve the CreatedDate of the last record creates of every custom object. But the only way I find to do it is by doing a dynamic query in a For or loop. But I’m, of course, limited to 100 custom objects. Did anyone have a solution to avoid the query in the loop ? Or any other workaround ? Thanks

I give you a sample of my code :

public void  method() {
    List<ObjectBuilder__c> listOfRecord = new List<ObjectBuilder__c> () ;       
    for(Schema.SObjectType objTyp : Schema.getGlobalDescribe().Values())
    {
        ObjectBuilder__c oneRecord = new ObjectBuilder__c ()  ; 
        Schema.DescribeSObjectResult describeSObjectResultObj = objTyp.getDescribe();
        objectName = objTyp.getDescribe().getLabel() ; 

        if(describeSObjectResultObj.isCustom() ) {
            if(!name.containsignorecase('history') && !name.containsignorecase('tag')&&
             !name.containsignorecase('share') && !name.containsignorecase('feed') ) {
                oneRecord.Api_Name__c = objTyp.getDescribe().getName(); ; 
                List<sObject> tmp = Database.query('SELECT CreatedDate  FROM '+ oneRecord.Api_Name__c +' order by CreatedDate  desc limit 1 ');
                System.debug('tmp list '+tmp);
                for(sObject obj :tmp ) {
                    oneRecord.Last_Used_Date__c =Date.valueOf(obj.get('CreatedDate')) ; 
                    listOfRecord.add(oneRecord) ;              
                }                      
             }
        }

    }

    INSERT listOfRecord ;

} `
share|improve this question
    
What are you trying to do? – Rahul Sharma 9 hours ago
    
I'm trying to store the last time a record was created in every custom object. With that information I can make a report and know which object is used or not for the last 3/6/9/12 months.. – SF Dev 9 hours ago

Each type of record does have to be queried separately so using a batchable to break up the work into less than 100 types per transaction is how I would approach this:

public class MyBatchable implements Database.Batchable<String> {

    public static void executeAsync() {
        Database.executeBatch(new MyBatchable(), 50);
    }

    public  String[] start(Database.BatchableContext bc) {
        // Return all the types (hundreds)
        String[] types = ...;
        return types;
    }

    public void execute(Database.BatchableContext bc, String[] scope) {
        ObjectBuilder__c[] records = new ObjectBuilder__c[] {};
        // Query the scope types (less than 100)
        insert records;
    }

    public void finish(Database.BatchableContext bc) {
    }
}

then:

MyBatchable.executeAsync();
share|improve this answer
    
Ha. Great minds, I guess. Asynchronous query limit is 200, though. Might as well use the greatest available value. – Adrian Larson 9 hours ago
    
@AdrianLarson Yep good point. – Keith C 7 hours ago

You could use a batch to get this sort of information. Something like:

public class DemoBatch implements Database.Batchable<SObjectType>
{
    public List<SObjectType> start(Database.BatchableContext context)
    {
        return Schema.getGlobalDescribe().values();
    }
    public void execute(Database.BatchableContext context, List<SObjectType> types)
    {
        List<MyObject__c> records = new List<MyObject__c>();
        for (SObjectType type : types)
        {
            Datetime createdDate = getMostRecentCreatedDate(type);
            if (createdDate != null) records.add(new MyObject__c(
                Api_Name__c = String.valueOf(type),
                Last_Created_Date__c = createdDate
            ));
        }
        insert records;
    }
    public void finish(Database.BatchableContext context) { }

    public static Datetime getMostRecentCreatedDate(SObjectType type)
    {
        try
        {
            List<SObject> records = Database.query(
                'SELECT CreatedDate FROM ' + type + ' ORDER BY CreatedDate DESC LIMIT 1'
            );
            return records.isEmpty() ? null : (Datetime)records[0].get('CreatedDate');
        }
        catch (QueryException q) { return null; }
    }
}

Then execute it with a batch size that will not exceed your governor limits:

Database.execute(new DemoBatch()); // limit is 200 in the asynchronous context
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.