62

Good question, but there are MANY possible answers, so I will just throw in my 2 cents. The first and easiest way to 'BULKIFY' is to leverage collections in order to save yourself SOQL calls and DML statements. Here's an older, but still great resource by Jeff Douglass on utilizing collections in Salesforce. http://blog.jeffdouglas.com/2011/01/06/fun-...


21

First, here's a link to Developer Force's Current List of Best Practices for Logic which has links to several articles that apply to bulkifying your code. Here's a link to the Trigger Pattern for Tidy, Streamlined, Bulkified Triggers which is a good place to start if you'd like to implement your triggers as classes and have any and all code for for a ...


16

The first key to Bulkification is removing SOQL and DML from loops (there are others, but this seems to be your biggest issue above). You need to leverage collections to help you do this. While I won't rewrite your trigger for you, I will give you some starting points. In your trigger above you have a SOQL query for every record in trigger.new. So for ...


13

Even if you are 100% sure that there is no possibility you will not have 200 attachments to modify, you also have to think that other code might execute in the same execution context and if the code you are creating is not efficient, it might impact the code that would have succeeded if the resources used by your code were lower. So always optimise your ...


12

You can submit multiple Records for approval, sample code below. List<Approval.ProcessSubmitRequest> requests = new List<Approval.ProcessSubmitRequest> (); for (Id oppId: opportunities) { Approval.ProcessSubmitRequest req1 = new Approval.ProcessSubmitRequest(); req1.setComments('Submitting request for ...


11

Your trigger is bulkified, so would make one call to the @future method for every 200 records that are loaded. As long as your call-out method can handle lists, and it appears that it can based on the way the way you've written the code to make the call to it, it would appear that you should be fine. The only potential issue would be any limits associated ...


9

This could be a tough one! Might depend on how many rows you need at once in a bulk operation? So the original WHERE clause looks like: (DetailName__c = 'abcde' AND Step__c = 12345) and at first I'm thinking a bulkified WHERE clause could look like: (DetailName__c = 'abcde' AND Step__c = 12345) OR (DetailName__c = 'fghij' AND Step__c = 23456) OR (...


9

100%. Currently you have a SOQL query inside a for loop. You should never ever do that for whatever reason. Instead you can utilise collections that are available in apex which allow you to avoid that (list, set, map). Read this article for more info on how to avoid this problem. Here is a quick re-write of your current code that should help you get started ...


9

It's one DML and SOQL per 200 records or a single DML "chunk." To illustrate this, consider the following code: contact[] c = [select id from contact limit 5]; id accountid = [select id from account where ispersonaccount = false limit 1].id; c.add(new contact(lastname='test1', accountid=accountid)); c.add(new contact(lastname='test2', accountid=accountid));...


8

@Shebin answered your specific question, but there are a few issue with your trigger, the most important being that it is not bulkified. you always want to avoid SOQL inside loops. Something like below is a bit safer to use trigger AccountDuplicateTrigger on Account (before insert,before update) { //You may need to filter this a bit more if you have ...


8

Thanks to Andrew Fawcett and his amazingly powerful UnitOfWork implementation I was able to create a base class to create amazingly simple Builder classes per Domain object. Those not only have the general benefits of TestDataBuilders over Helper classes but also: Care about the DML as pure In-Memory tests are harder on Force.com Take care of bulkification ...


8

It should instead be: List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>(); for Opportunity record : records) { Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage() // set properties on singular email emails.add(email); } Messaging.sendEmail(emails);


7

Two important things to keep in mind for bulkifying code is to: Avoid SOQL inside for loops Performing DML operations such insert/updates on a List of objects instead of a single object inside a loop. Move your SOQL statement outside the loop and store the data in a List/Map. Also add the objects that need to be updated into a List and perform one ...


7

First, you should try to follow the DRY pattern; by moving some logic around, we can reduce your code by almost half: trigger Order_PopulateGallery on RH_Order__c (before insert, before update){ List<Account> accs = new List<Account>(); for(RH_Order__c ord : Trigger.new){ if(ord.Gallery_Number__c == null) { ord....


7

You should always use collection like Map and Set to hold values which you will need later while for-loop iteration. Something like that: Group Tccqueue = [SELECT Id, name FROM Group WHERE type='Queue' and Name='TCC Counsellors' Limit 1]; Map<Id,GroupMember> queueMembers = new Map<Id,GroupMember>(); for(GroupMember gm : [SELECT Group.Name, ...


6

There are a number of ways records can be inserted into objects. Use of DML via Apex through your own code is of course one. Here you can of course determine how many records are inserted at once. However the Force.com platform is a very open platform. There are numerous API's (Enterprise, Partner, REST) and also Data Loader tools (utilising these API's) ...


6

Try this. As said above, the main points are to remove SOQL & DML statement from any loops. trigger updateSerialList on Meter_Serial_Info__c(Before insert, Before update, Before delete) { if (Trigger.isDelete || Trigger.isUpdate) { Set<Id> serialIds = new Set<Id>(); for (Meter_Serial_Info__c msio : Trigger.old) { ...


6

Salesforce won't combine operations from different transactions, especially from different users. The only time you'll see bulk operations is when multiple records are created/updated/deleted together by an app.


6

I would start off by putting the different locations in maps. So something like: List<Inventory_Lots__c> icList = [SELECT Id, Location__c, Closed__c, On_Hold__c from Inventory_Lots__c WHERE Location__c IN :recIds.Keyset() AND Closed__c != TRUE AND On_Hold__c != TRUE]; Map<Id, List<Inventory_Lots__c> lotByLocation = new Map<Id, List<...


6

You are adding the entire trigger context to your maps for each execution of the loop on a single record then you are calling a method that updates records based on this list each execution of the for loop. Basically if you had 200 records in context you would be processing each set of 200 records 200 times and performing up to 200 dml statements if all of ...


6

There is no Harm in adding this bulkification. NEVER say never....you could find the need to do a mass upload of attachments in the future, or another admin could do it as well. ESPECIALLY since you already have the code written, go with the bulkified. In my opinion, I'd rather have something in place that I might never need, but be all set in the off ...


6

(What follows may contain bits of heresy..... and applies mostly to non managed package use cases) The reason to do bulk testing (> 100 records) is to ferret out bad bulkification practices in the code being tested - which might include code written by yourself or by others. The reason to do bulk testing with more than 200 records is to ferret out ...


6

The system never optimizes triggers or flows of its own accord. You will need need to gather all the relevant ID values and then call the flow. However, you should be wary of using flows in bulk anyways, because they tend to consume a lot more CPU time than simply writing Apex Code. When you call a flow, it runs synchronously, as if you'd just called another ...


6

Yes, you will get the 101 query exception1. The reason is that all of the trigger "chunks" (I prefer using "chunk" over "batch", because "batch" in Salesforce is a separate thing) are part of the same transaction, and governor limits are enforced per-transaction. If you use one query in your trigger, then your trigger can handle (at most) 20,000 records. ...


5

Trigger.New is a list of sObjects. If you want a set of keys you want to use trigger.newMap. This is a map of the objects in trigger.new with the ID as the key and the object as the value. So you are trying to call keyset(), which is a map method, on a list. From the docs Trigger.new - Returns a list of the new versions of the sObject records. ...


5

One other thing to consider: If you use triggers, you are forced to write testmethods and if you do a good job of this (lots of asserts, positive and negative tests, ...), you'll end up with a comprehensive set of regression tests If you use Process Builder, this testing requirement has to be met in other ways: A browser automated testing tool (Selenium) ...


5

Try this. Instead of directly inserting the opportunity. Add them to a list and insert the list after the for loop. List<Opportunity> newOppList = new List<Opportunity>(); List < Opportunity_car_set__c > lstOppCarset=[SELECT Name,Model__r.IsActive,Version__r.IsActive FROM Opportunity_car_set__c where Opportunity__c = : opp.id]; for (...


5

Your code does not look like it will have any bulk issues. You do need to check if the setting is null though, since you are not guaranteed to have a CountryInfo__c record for a given key. CountryInfo__c setting = CountryInfo__c.getValues(acc.Country_Information__c); if (setting != null) acc.Description = setting.Capital__c; I also strongly advise you to ...


5

You can do it like this: // Your map Map<Id, String> m = new Map<Id, String>(); // Update needs to know the type so create objects of the right type Opportunity[] updates = new Opportunity[] {}; for (Id id : m.keySet()) { updates.add(new Opportunity(Id = id, FieldName__c = m.get(id))); } update updates; Note that there is also a put(String ...


5

Like I said in my comment, the key to bulkifying code in Salesforce is to remove all DML and SOQL from the inside of loops. The reason why this is important is because you're only allowed 100 SOQL queries and 150 DML statements per (synchronous) transaction, and a trigger (or rather, the trigger context variables) can easily contain more than 100 records. ...


Only top voted, non community-wiki answers of a minimum length are eligible