Skip to main content

#Apex48 人がディスカッション中

We need to find Accounts that have Contacts whose Department is "IT", and print the Account Name along with the number of IT Contacts.

I tried this:

for (Account acc : [

SELECT Id, Name, (SELECT Id, Name, Department FROM Contacts)

FROM Account

]) {

Integer count = 0;

for (Contact con : acc.Contacts) {

if (con.Department == 'IT') {

count++;

}

}

System.debug(acc.Name + ' → IT Contacts: ' + count);

}

My question:

 

Why is acc.Contacts available inside the outer loop even though we didn't execute a separate SOQL query for Contacts?

Also, what happens if an Account has a very large number of Contacts? Is there a better/bulk-safe approach than using the nested loop

 

#Apex  #Salesforce Developer

3 件の回答
  1. 今日、16:47

    Hi @Rohit .

     

    acc.Contacts is available because the query uses a Parent-to-Child Relationship Query:

    SELECT Id, Name,       (SELECT Id, Name, Department FROM Contacts)FROM Account

    The child Contacts are retrieved as part of the same SOQL query and stored in the acc.Contacts relationship collection. Therefore, no separate SOQL query is required inside the loop. 

     

    Regarding a large number of Contacts, the nested loop is valid, but retrieving every Contact just to count IT Contacts may be inefficient. If we only need the count, an Aggregate SOQL query

     with COUNT() and GROUP BY AccountId would be more efficient because the database performs the counting instead of Apex. 

     

    So, use the relationship query when you need to process Contact records; use Aggregate SOQL when you only need counts/statistics

    .  

     

    Hope this help !!.

0/9000
Hi,

I have a use case where I am creating a case using Email-to-Case. I need to edit the case description (which is the body of the email) using apex but I'm getting the following error

System.DmlException: Update failed. First exception on row 0 with id 02sHr00001an6LHIAY; first error: INVALID_OPERATION, operation is not allowed: [].

Is it possible to edit an EmailMessage in this case? Please suggest the steps to do so
3 件の回答
  1. 2023年5月30日 17:29
    Hello Abhishek ,

    EmailMessage can be updated only when it's in the Draft status.

    Update() is supported when an email record is in Draft status, and IsPrivateDraft is false. It is also supported if Status and IsPrivateDraft are true and CreatedBy is associated with the current user. When the email record status is not in Draft status, the IsExternallyVisible field and custom fields only can be updated.

    Reference -> https://salesforce.stackexchange.com/questions/312390/receiving-illegal-operation-error-on-emailmessage-update-from-contentdocumentlin

    Hope this helps !

    Thank you.
0/9000

 Which is faster for checking whether a record exists: SOQL inside a loop or one SOQL query outside the loop? and what happens if you perform DML on 200 records one-by-one inside a loop?  

 

#Apex

5 件の回答
  1. 今日、6:34

    Hi @Pranjal Budhlakoti

     

     A single SOQL query outside the loop is faster and follows Apex best practices. SOQL inside a loop can quickly hit the SOQL governor limit. 

     

    Similarly, performing DML one-by-one inside a loop is not recommended. For 200 records, it can consume 200 DML statements and exceed the 150 DML statement limit. 

     

    The best approach is to query records once, process them in a loop, and perform DML once using a List. This makes the code bulkified and governor-limit safe.  

     

    Thank You.

0/9000
6 件の回答
  1. 今日、11:04

    @Hitesh SharmaHitesh, for a beginner I recommend this roadmap:

    Apex Basics → Variables/Conditions/Loops → List/Set/Map → sObjects → SOQL → DML → Classes → Exceptions → Governor Limits & Bulkification → Triggers → Test Classes → Async Apex → REST/Callouts.

    Start with the official Trailhead Quick Start: Apex, then Apex Basics & Database. Trailhead Quick Start: Apex Apex Basics & Database

    For reference, use the official Apex Developer Guide

0/9000

Main Code:  

public class NewConstEx { 

public list<string> subjects; 

    public NewConstEx(list<string> subjectlist){ 

        subjects=subjectlist; 

    } 

 

anonymous Window:  

list<string> mysubject = new list<string>{ 

    'Apex', 

        'LWC', 

        'JS', 

        'Java' 

}; 

NewConstEx N = new NewConstEx(mysubject); 

system.debug(N.subjects); 

 

#Apex  #Salesforce Developer

2 件の回答
  1. 今日、11:05

    @Himanshu Shekhar Yes, you can declare the List in the main Apex class itself.

    For example:

    public class NewConstEx {

    public List<String> subjects = new List<String>{

    'Apex',

    'LWC',

    'JS',

    'Java'

    };

    public NewConstEx() {

    }

    }

    Then Anonymous Window:

    NewConstEx N = new NewConstEx();

    System.debug(N.subjects);

    Your original approach is also correct:

    List<String> mysubject = new List<String>{'Apex', 'LWC', 'JS', 'Java'};

    NewConstEx N = new NewConstEx(mysubject);

    Constructor is useful when you want to pass different Lists/values from outside. If the List is always fixed, you can initialize it directly in the class. 

0/9000
4 件の回答
  1. 今日、11:06

    @Hitesh Sharma for learning SOQL from scratch, follow this order:

    Basics → SELECT/FROM → WHERE → AND/OR/IN → ORDER BY → LIMIT → LIKE → NULL → Relationship Queries → Aggregate Functions → GROUP BY/HAVING → SOQL in Apex → Bind Variables.

    The official SOQL for Admins Trailhead module covers these topics with hands-on practice. SOQL for Admins – Trailhead 

0/9000
5 件の回答
  1. 今日、11:09

    @Hitesh Sharma  

    Apex Basics → Variables/Conditions/Loops → List/Set/Map → sObjects → SOQL/SOSL → DML → Classes/Methods → Constructors → Triggers → Governor Limits & Bulkification → Test Classes → Async Apex → Integrations.

    Practice every topic with small programs in Developer Console/VS Code.

    Start with Salesforce's Apex Basics & Database module, then move to Apex Triggers and Apex Testing. Apex Basics & Database – Trailhead Apex Developer Guide 

0/9000
4 件の回答
  1. 今日、11:37

    Hi @Hitesh Sharma

      

    You can use 

    VS Code with the Salesforce Extension Pack and Salesforce CLI to retrieve Apex, LWC, and other metadata from your Salesforce org. 

    After authorizing the org, use SFDX: Retrieve Source from Org in VS Code to retrieve the required components. 

    For JSON files, it depends on where they are stored: 

    • Static Resource/LWC bundle → retrieve the corresponding metadata. 
    • Salesforce record/data → use SOQL, Data Loader, or another data-export tool. 

     

    Hope this helps! 

0/9000
3 件の回答
  1. 8月26日 7:07

    Hello @Hitesh Sharma

     

    Lists, Sets, and Maps are fundamental Apex collection types in Salesforce, differing primarily in how they organize, store, and retrieve data. 

     

    1. List (Ordered Shopping List) 

       What it is: A row of items kept in the exact order you put them in. You can have identical items twice. 

       Salesforce Use Case: Holding a batch of records straight out of a database query (like a list of 50 new Contacts) where sequence matters. 

    2. Set (Unique ID Bag) 

       What it is: A bag that holds items, but no duplicates are allowed. If you drop the same item in twice, it only stays once. 

       Salesforce Use Case: Collecting unique Account IDs from incoming records so you can search the database safely without running duplicate queries. 

    3. Map (Name-to-Phone Number Directory) 

       What it is: A pair system where a unique "Key" points to a specific "Value" (like a person's name linked to their phone number). 

       Salesforce Use Case: Matching a record ID (Key) directly to its parent Account or Contact record (Value) for instant lookup. 

     

    Best Practices 

    - No Queries in Loops: Never run database queries inside loops; fetch data into a List or Map first. 

    - Use Sets for IDs: Put record IDs into a Set when filtering via WHERE Id IN :mySet to keep code clean and fast. 

    - Pick the Right Tool: Use a List for order, a Set for uniqueness, and a Map when you need to find a record instantly by its ID

0/9000

 An organization wants to automatically maintain an Account's Customer_Tier__c based on its Opportunities.  

 

Rules: 

  •  If Account has at least one Closed Won Opportunity with Amount >= $100,000, set Customer_Tier__c = 'Platinum'. 
  •  If it has a Closed Won Opportunity with Amount between $50,000–$99,999, set it to Gold. 
  •  Otherwise, set it to Silver. 
  •  The logic must work when Opportunities are inserted, updated, deleted, or undeleted. 
  •  It must handle bulk transactions. 
  •  No SOQL/DML inside loops. 
  •  The solution should use a Trigger Handler pattern.

Q.  How would you design this trigger and handler? Which trigger events would you use, and how would you efficiently recalculate the Account tier when an Opportunity is deleted or its Amount/Stage changes? 

  

 

#Salesforce Developer  #Apex  #Salesforce

3 件の回答
  1. 今日、6:19

    @Deepak Sharma

    I would use an after-trigger for all four events because the Account tier depends on the current set of Opportunities. Insert and undelete can introduce a qualifying Opportunity, update can change Amount, Stage, or Account, and delete can remove the Opportunity that previously determined the tier.  

    For update, I collect both the old and new Account IDs so that an Opportunity moving between Accounts recalculates both Accounts.  

    The handler passes a Set of Account IDs to a service class, which performs bulk SOQL, calculates the highest applicable tier in memory, and performs a single bulk Account update. This avoids SOQL and DML inside loops and handles bulk transactions safely.  

0/9000