일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- platform developer1
- development link
- sObject
- Administrator
- Too many SOQL queries
- object setting
- BASIC
- dump
- sharing
- VARIABLE
- apex class
- Too many DML statements
- Database Methods
- service cloud consultant
- apex
- chatter user profile
- difference with java
- sales cloud consultant
- developer console
- deactivate record type for chatter user profile
- DML Statement
- google extension
- salesforce
- System.LimitException
- Today
- Total
어느 Salesforce Developer의 개발 성장기
Salesforce 신입 개발자가 가장 많이 하는 실수(System.LimitException: Too many SOQL queries / Too many DML statements) 본문
Salesforce 신입 개발자가 가장 많이 하는 실수(System.LimitException: Too many SOQL queries / Too many DML statements)
Developer_Foryou 2020. 3. 11. 00:10Salesforce는 동기 Apex에 대해 100개의 SOQL 쿼리 또는 비동기 Apex에 대해 200개의 SOQL 쿼리 제한이 있다.
즉, 반복문(for문) 안에서 쿼리문을 사용하면 안된다.
Performing Bulk SOQL
SOQL 검색시, 잘못된 쿼리 예시(1):
trigger SoqlTriggerNotBulk on Account(after update) {
for(Account a : Trigger.New) {
// Get child records for each account
// Inefficient SOQL query as it runs once for each account!
Opportunity[] opps = [SELECT Id,Name,CloseDate
FROM Opportunity WHERE AccountId=:a.Id];
// Do some other processing
}
}
위 코드는 Trigger가 발동되는 레코드가 많을 때, System.LimitException을 발생시킬 수 있다.
SOQL 쿼리 제한을 피하기 위해 다음과 같이 코드를 작성해야 한다.
SOQL 검색시, 올바른 쿼리 예시(1):
trigger SoqlTriggerBulk on Account(after update) {
// Perform SOQL query once.
// Get the accounts and their related opportunities.
List<Account> acctsWithOpps =
[SELECT Id,(SELECT Id,Name,CloseDate FROM Opportunities)
FROM Account WHERE Id IN :Trigger.New];
// Iterate over the returned accounts
for(Account a : acctsWithOpps) {
Opportunity[] relatedOpps = a.Opportunities;
// Do some other processing
}
}
SOQL 검색시, 올바른 쿼리 예시(2): 계정의 레코드가 필요하지 않은 경우 이 Trigger Context 내의 계정과 관련된 기회만 검색할 수 있다.
trigger SoqlTriggerBulk on Account(after update) {
// Perform SOQL query once.
// Get the related opportunities for the accounts in this trigger.
List<Opportunity> relatedOpps = [SELECT Id,Name,CloseDate FROM Opportunity
WHERE AccountId IN :Trigger.New];
// Iterate over the related opportunities
for(Opportunity opp : relatedOpps) {
// Do some other processing
}
}
SOQL 검색시, 올바른 쿼리 예시(3): 하나의 명령문에서 for루프를 사용하여 SOQL 쿼리를 결합하면 이전 예제의 크기를 줄일 수 있다.
trigger SoqlTriggerBulk on Account(after update) {
// Perform SOQL query once.
// Get the related opportunities for the accounts in this trigger,
// and iterate over those records.
for(Opportunity opp : [SELECT Id,Name,CloseDate FROM Opportunity
WHERE AccountId IN :Trigger.New]) {
// Do some other processing
}
}
Bulk SOQL이 진행된 경우, 트리거는 한 번에 200 레코드씩 일괄적으로 실행한다. 따라서 400개의 레코드가 트리거를 발생시키면 트리거는 200개의 레코드 당 1번씩 2번 트리거된다.
Performing Bulk DML
Trigger나 Class에서 DML호출을 수행할 때는 가능하면 sObject Collection에서 DML호출을 수행하자.
각 sObject에서 DML을 수행하면 비효율적으로 리소스가 개별적으로 사용된다.
(Apex Runtime은 하나의 transaction에서 150개의 DML호출을 허용한다.
DML 실행 시, 잘못된 쿼리 예시(1):
trigger DmlTriggerNotBulk on Account(after update) {
// Get the related opportunities for the accounts in this trigger.
List<Opportunity> relatedOpps = [SELECT Id,Name,Probability FROM Opportunity
WHERE AccountId IN :Trigger.New];
// Iterate over the related opportunities
for(Opportunity opp : relatedOpps) {
// Update the description when probability is greater
// than 50% but less than 100%
if ((opp.Probability >= 50) && (opp.Probability < 100)) {
opp.Description = 'New description for opportunity.';
// Update once for each opportunity -- not efficient!
update opp;
}
}
}
DML 실행 시, 올바른 쿼리 예시(1): List에 레코드를 담아서 한번에 Update
trigger DmlTriggerBulk on Account(after update) {
// Get the related opportunities for the accounts in this trigger.
List<Opportunity> relatedOpps = [SELECT Id,Name,Probability FROM Opportunity
WHERE AccountId IN :Trigger.New];
List<Opportunity> oppsToUpdate = new List<Opportunity>();
// Iterate over the related opportunities
for(Opportunity opp : relatedOpps) {
// Update the description when probability is greater
// than 50% but less than 100%
if ((opp.Probability >= 50) && (opp.Probability < 100)) {
opp.Description = 'New description for opportunity.';
oppsToUpdate.add(opp);
}
}
// Perform DML on a collection
update oppsToUpdate;
}
'Salesforce > Tips' 카테고리의 다른 글
Chatter 사용자에게 설정된 레코드 유형 비활성화하기 (0) | 2020.03.10 |
---|