๋๋ Apex ํธ๋ฆฌ๊ฑฐ
ํ์ต ๋ชฉํ
์ด ์ ๋์ ์๋ฃํ๋ฉด ๋ค์์ ์ํํ ์ ์์ต๋๋ค.
- sObject ์ปฌ๋ ์
์์ ์๋ํ๋ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
- ํจ์จ์ ์ธ SOQL ๋ฐ DML ์์
์ ์ํํ๋ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
๋๋ ํธ๋ฆฌ๊ฑฐ ๋์์ธ ํจํด
Apex ํธ๋ฆฌ๊ฑฐ๋ ๋๋์ผ๋ก ์๋ํ๋ ๋ฐ ์ต์ ํ๋์ด ์์ต๋๋ค. ํธ๋ฆฌ๊ฑฐ์์ ๋ ์ฝ๋๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๋๋ ๋์์ธ ํจํด์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋๋ ๋์์ธ ํจํด์ ์ฌ์ฉํ ๊ฒฝ์ฐ ํธ๋ฆฌ๊ฑฐ์ ์ฑ๋ฅ์ด ํฅ์๋๊ณ ์๋ฒ ๋ฆฌ์์ค ์ฌ์ฉ๋์ด ์ค์ด ํ๋ซํผ ์ ํ์ ์ด๊ณผํ ๊ฐ๋ฅ์ฑ์ด ๋ฎ์์ง๋๋ค.
์ฝ๋๋ฅผ ๋๋์ผ๋ก ์ฒ๋ฆฌํ ๊ฒฝ์ฐ ๋๋์ผ๋ก ์ฒ๋ฆฌ๋ ์ฝ๋๊ฐ ๋ง์ ์์ ๋ ์ฝ๋๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ Salesforce Platform์ ๊ฑฐ๋ฒ๋ ์ ํ ๋ด์์ ์คํํ ์ ์๋ค๋ ์ด์ ์ด ์์ต๋๋ค. ์ด๋ฌํ ๊ฑฐ๋ฒ๋ ์ ํ์ ๋ฐ์ด์จ์ด ์ฝ๋๊ฐ ๋ค์ค ํ ๋ํธ ํ๋ซํผ์์ ๋ฆฌ์์ค๋ฅผ ๋ ์ ํ์ง ์๋๋ก ๋ฐฉ์งํ๊ธฐ ์ํ ๊ฒ์ ๋๋ค.
๋ค์ ์น์
์์๋ ํธ๋ฆฌ๊ฑฐ์ ๋ชจ๋ ๋ ์ฝ๋์์ ์๋ํ๊ณ ๋จ์ผ sObject ๋์ sObject ์ปฌ๋ ์
์์ SOQL ๋ฐ DML์ ์ํํ๋ ๋ฑ, ํธ๋ฆฌ๊ฑฐ์์ Apex ์ฝ๋๋ฅผ ๋๋์ผ๋ก ์ฒ๋ฆฌํ๋ ์ฃผ์ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค. SOQL ๋ฐ DML ๋๋ ๋ชจ๋ฒ ์ฌ๋ก๋ ํด๋์ค์ SOQL ๋ฐ DML์ ํฌํจํ์ฌ ๋ชจ๋ Apex ์ฝ๋์ ์ ์ฉ๋ฉ๋๋ค. ์ฃผ์ด์ง ์์ ๋ ํธ๋ฆฌ๊ฑฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ฉฐ Trigger.new ์ปจํ
์คํธ ๋ณ์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋ ์ฝ๋ ์งํฉ์ ๋ํด ์์ ํ๊ธฐ
๋จผ์ ํธ๋ฆฌ๊ฑฐ์์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๋๋ ๋์์ธ ๊ฐ๋ ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ๋๋์ผ๋ก ์ฒ๋ฆฌ๋ ํธ๋ฆฌ๊ฑฐ๋ ํธ๋ฆฌ๊ฑฐ ์ปจํ ์คํธ์ ๋ชจ๋ sObject์์ ์๋ํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ํธ๋ฆฌ๊ฑฐ๋ฅผ ์คํํ ์์ ์ด ์ฌ์ฉ์ ์ธํฐํ์ด์ค์์ ์์๋ ๊ฒฝ์ฐ ํธ๋ฆฌ๊ฑฐ๋ ํ๋์ ๋ ์ฝ๋์์ ์๋ํฉ๋๋ค. ๊ทธ๋ฌ๋ ์์ ์ ์ถ์ฒ๊ฐ ๋๋ DML ๋๋ API์ธ ๊ฒฝ์ฐ ํธ๋ฆฌ๊ฑฐ๋ ํ๋์ ๋ ์ฝ๋๊ฐ ์๋ ๋ ์ฝ๋ ์งํฉ์์ ์๋ํฉ๋๋ค. ์๋ฅผ ๋ค์ด API๋ฅผ ํตํด ๋ง์ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ์ฌ ๊ฒฝ์ฐ ํธ๋ฆฌ๊ฑฐ๋ ์ ์ฒด ๋ ์ฝ๋ ์งํฉ์์ ์๋ํฉ๋๋ค. ๋ฐ๋ผ์ ์ ์ ํ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ๋ฒ์ ํธ๋ฆฌ๊ฑฐ๊ฐ ๋ชจ๋ ์ํฉ์์ ์๋ํ๋๋ก ๋ ์ฝ๋ ์ปฌ๋ ์ ์์ ์๋ํ๋ค๊ณ ํญ์ ๊ฐ์ ํ๋ ๊ฒ์ ๋๋ค.
๋ค์ ํธ๋ฆฌ๊ฑฐ(MyTriggerNotBulk)๋ ์ค๋ก์ง ํ๋์ ๋ ์ฝ๋๋ง ํธ๋ฆฌ๊ฑฐ๋ฅผ ์๋ํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค. ์ด ํธ๋ฆฌ๊ฑฐ๋ ๋์ผํ ํธ๋์ญ์
์ ์ฌ๋ฌ ๋ ์ฝ๋๊ฐ ์ฝ์
๋ ๊ฒฝ์ฐ ์ ์ฒด ๋ ์ฝ๋ ์งํฉ์์ ์๋ํ์ง ์์ต๋๋ค. ๋ค์ ์์ ์์๋ ๋๋์ผ๋ก ์ฒ๋ฆฌ๋ ๋ฒ์ ์ ๋ณด์ฌ์ค๋๋ค.
trigger MyTriggerNotBulk on Account(before insert) {
Account a = Trigger.new[0];
a.Description = 'New description';
}์ด ์์ (MyTriggerBulk)๋ MyTriggerNotBulk์ ์์ ๋ ๋ฒ์ ์
๋๋ค. for ๋ฃจํ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ sObject๋ฅผ ๋ฐ๋ณตํฉ๋๋ค. ์ด ๋ฃจํ๋ Trigger.new์ ํ๋์ sObject ๋๋ ์ฌ๋ฌ ๊ฐ์ sObject๊ฐ ํฌํ๋ ๊ฒฝ์ฐ ์๋ํฉ๋๋ค.
trigger MyTriggerBulk on Account(before insert) {
for(Account a : Trigger.new) {
a.Description = 'New description';
}
}๋๋ SOQL ์ํํ๊ธฐ
SOQL ์ฟผ๋ฆฌ๋ ๊ฐ๋ ฅํ ์ ์์ต๋๋ค. ๋จ์ผ ์ฟผ๋ฆฌ์์ ๊ด๋ จ ๋ ์ฝ๋๋ฅผ ๊ฒ์ํ๊ณ ์ฌ๋ฌ ์กฐ๊ฑด์ ์กฐํฉ์ ํ์ธํ ์ ์์ต๋๋ค. SOQL ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด ๋ ์ ์ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํ ์ฟผ๋ฆฌ๋ฅผ ๋ ์ ๊ฒ ์์ฑํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฟผ๋ฆฌ ์๋ฅผ ์ค์ผ ๊ฒฝ์ฐ ๋๊ธฐ Apex์ ๊ฒฝ์ฐ 100๊ฐ์ SOQL ์ฟผ๋ฆฌ ๋๋ ๋น๋๊ธฐ์ Apex์ ๊ฒฝ์ฐ 200๊ฐ์ธ ์ฟผ๋ฆฌ ์ ํ์ ๋๋ฌํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
๋ค์ ํธ๋ฆฌ๊ฑฐ(SoqlTriggerNotBulk)๋ ํผํด์ผ ํ SOQL ์ฟผ๋ฆฌ ํจํด์ ๋ณด์ฌ์ค๋๋ค. ์์ ์์๋ for ๋ฃจํ ๋ด์์ SOQL ์ฟผ๋ฆฌ๋ฅผ ๋ง๋ค์ด ๊ฐ ๊ณ์ ์ ๋ํ ๊ด๋ จ ๊ธฐํ๋ฅผ ๊ฐ์ ธ์ค๋ฉฐ, ์ด ์ฟผ๋ฆฌ๋ Trigger.new์ ๊ฐ ๊ณ์ sObject์ ๋ํด ํ ๋ฒ ์คํ๋ฉ๋๋ค. ๊ณ์ ๋ชฉ๋ก์ด ๋ง์ ๊ฒฝ์ฐ for ๋ฃจํ ๋ด๋ถ์ SOQL ์ฟผ๋ฆฌ๋ก ์ธํด SOQL ์ฟผ๋ฆฌ๊ฐ ๋๋ฌด ๋ง์ด ๋ฐ์ํ ์ ์์ต๋๋ค. ๋ค์ ์์ ์์ ๊ถ์ฅ๋๋ ์ ๊ทผ ๋ฐฉ์์ ๋ณด์ฌ์ค๋๋ค.
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
}
}๋ค์ ์์ (SoqlTriggerBulk)๋ ์ด์ ์์ ๋ฅผ ์์ ํ ๋ฒ์ ์ผ๋ก์ SOQL ์ฟผ๋ฆฌ ์คํ์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ณด์ฌ์ค๋๋ค. SOQL ์ฟผ๋ฆฌ๋ ๋ฌด๊ฑฐ์ด ์์
์ ์ํํ๊ณ ๊ธฐ๋ณธ ๋ฃจํ ์ธ๋ถ์์ ํ ๋ฒ ํธ์ถ๋ฉ๋๋ค.
- SOQL ์ฟผ๋ฆฌ๋ ๊ณ์ ์ ๋ด๋ถ ์ฟผ๋ฆฌ(
SELECT Id FROM Opportunities)๋ฅผ ์ฌ์ฉํ์ฌ ๊ณ์ ์ ๋ํ ๊ด๋ จ ๊ธฐํ๋ฅผ ๊ฐ์ ธ์ต๋๋ค. - SOQL ์ฟผ๋ฆฌ๋
IN์ ์ ์ฌ์ฉํ๊ณWHERE์ (WHERE Id IN :Trigger.new)์Trigger.new๋ณ์๋ฅผ ๋ฐ์ธ๋ฉํ์ฌ ํธ๋ฆฌ๊ฑฐ ์ปจํ ์คํธ ๋ ์ฝ๋์ ์ฐ๊ฒฐ๋ฉ๋๋ค. ์ดWHERE์กฐ๊ฑด์ ์ด ํธ๋ฆฌ๊ฑฐ๋ฅผ ์คํํ ๋ ์ฝ๋๋ก๋ง ๊ณ์ ์ ํํฐ๋งํฉ๋๋ค.
์ฟผ๋ฆฌ์ ๋ ๋ถ๋ถ์ ๊ฒฐํฉํ๋ฉด ๊ฐ ๊ณ์ ์ ๊ด๋ จ ๊ธฐํ๊ฐ ์๋ ์ด ํธ๋ฆฌ๊ฑฐ์ ๊ณ์ ์์ ํธ์ถ ํ ๋ฒ์ผ๋ก ์ํ๋ ๋ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
ํด๋น ๋ ์ฝ๋์ ๊ด๋ จ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ์จ ํ for ๋ฃจํ๋ ์ปฌ๋ ์
๋ณ์(์ด ๊ฒฝ์ฐ acctsWithOpps)๋ฅผ ์ฌ์ฉํ์ฌ ๊ด์ฌ์๋ ๋ ์ฝ๋๋ฅผ ๋ฐ๋ณตํฉ๋๋ค. ์ปฌ๋ ์
๋ณ์๋ SOQL ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ ํฉ๋๋ค. ๊ทธ๋ ๊ฒ ํ ๊ฒฝ์ฐ for ๋ฃจํ๋ ์์
ํ ๋ ์ฝ๋์ ๋ํด์๋ง ๋ฐ๋ณตํฉ๋๋ค. ๊ด๋ จ ๋ ์ฝ๋๋ฅผ ์ด๋ฏธ ๊ฐ์ ธ์์ผ๋ฏ๋ก ๋ฃจํ ๋ด์์ ํด๋น ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํ ์ถ๊ฐ ์ฟผ๋ฆฌ๋ ํ์ํ์ง ์์ต๋๋ค.
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
}
}๋๋ ๊ณ์ ์์ ๋ ์ฝ๋๊ฐ ํ์ํ์ง ์์ ๊ฒฝ์ฐ ์ด ํธ๋ฆฌ๊ฑฐ ์ปจํ
์คํธ ๋ด์์ ๊ณ์ ๊ณผ ๊ด๋ จ๋ ๊ธฐํ๋ง ๊ฒ์ํ ์ ์์ต๋๋ค. ์ด ๋ชฉ๋ก์ Trigger.new(WHERE AccountId IN :Trigger.new)์์ ๊ณ์ ID์ ๋ํ ๊ธฐํ์ AccountId ํ๋์ ์ผ์นํจ์ผ๋ก์จ WHERE ์ ์์ ์ง์ ๋ฉ๋๋ค. ๋ฐํ๋ ๊ธฐํ๋ ํน์ ๊ณ์ ์ด ์๋๋ผ ์ด ํธ๋ฆฌ๊ฑฐ ์ปจํ
์คํธ์ ๋ชจ๋ ๊ณ์ ์ ๋ํ ๊ธฐํ์
๋๋ค. ๋ค์ ์์ ์์๋ ๋ชจ๋ ๊ด๋ จ ๊ธฐํ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ ์ฌ์ฉ๋๋ ์ฟผ๋ฆฌ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
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 for ๋ฃจํ์์ SOQL ์ฟผ๋ฆฌ๋ฅผ for ๋ฃจํ์ ๊ฒฐํฉํ์ฌ ์ด์ ์์ ์ ํฌ๊ธฐ๋ฅผ ์ค์ผ ์ ์์ต๋๋ค. ๋ค์์ SOQL for ๋ฃจํ๋ฅผ ์ฌ์ฉํ๋ ์ด ๋๋ ํธ๋ฆฌ๊ฑฐ์ ๋ค๋ฅธ ๋ฒ์ ์
๋๋ค.
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
}
}๋๋ DML ์ํํ๊ธฐ
ํธ๋ฆฌ๊ฑฐ ๋๋ ํด๋์ค์์ DML ํธ์ถ์ ์ํํ ๋ ๊ฐ๋ฅํ ๊ฒฝ์ฐ sObject ์ปฌ๋ ์ ์ ๋ํด DML ํธ์ถ์ ์ํํฉ๋๋ค. ๊ฐ sObject์์ DML์ ๊ฐ๋ณ์ ์ผ๋ก ์ํํ๋ฉด ๋ฆฌ์์ค๊ฐ ๋นํจ์จ์ ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค. Apex ๋ฐํ์์ ํ๋์ ํธ๋์ญ์ ์์ ์ต๋ 150๊ฐ์ DML ํธ์ถ์ ํ์ฉํฉ๋๋ค.
์ด ํธ๋ฆฌ๊ฑฐ(DmlTriggerNotBulk)๋ ๊ด๋ จ ๊ธฐํ๋ค์ ๋ํ์ฌ ๋ฐ๋ณต๋๋ for ๋ฃจํ ๋ด์์ ์
๋ฐ์ดํธ ํธ์ถ์ ์ํํฉ๋๋ค. ํน์ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋ ๊ฒฝ์ฐ ํธ๋ฆฌ๊ฑฐ๊ฐ ๊ธฐํ ์ค๋ช
์ ์
๋ฐ์ดํธํฉ๋๋ค. ์ด ์์ ์์ update ๋ฌธ์ ๊ฐ ๊ธฐํ์ ๋ํด ํ ๋ฒ์ฉ ๋นํจ์จ์ ์ผ๋ก ํธ์ถ๋ฉ๋๋ค. ๋๋ ๊ณ์ ์
๋ฐ์ดํธ ์์
์ด ํธ๋ฆฌ๊ฑฐ๋ฅผ ์คํํ ๊ฒฝ์ฐ ๋ง์ ๊ณ์ ์ด ์์ ์ ์์ต๋๋ค. ๊ฐ ๊ณ์ ์ ํ๋ ๋๋ ๋ ๊ฐ์ ๊ธฐํ๊ฐ ์๋ ๊ฒฝ์ฐ 150๊ฐ ์ด์์ ๊ธฐํ๋ก ์ฝ๊ฒ ๋๋ ์ ์์ต๋๋ค. DML ๋ฌธ ์ ํ์ 150๊ฐ ํธ์ถ์
๋๋ค.
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;
}
}
}๋ค์ ์์ (DmlTriggerBulk)๋ ๊ธฐํ ๋ชฉ๋ก์์ ๋จ ํ๋์ DML ํธ์ถ๋ก DML์ ํจ์จ์ ์ผ๋ก ๋๋์ผ๋ก ์ํํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค. ์ด ์์ ์์๋ ๋ฃจํ์์ ๊ธฐํ(oppsToUpdate) ๋ชฉ๋ก์ ์
๋ฐ์ดํธํ Opportunity sObject๋ฅผ ์ถ๊ฐํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ํธ๋ฆฌ๊ฑฐ๋ ๋ชจ๋ ๊ธฐํ๊ฐ ๋ชฉ๋ก์ ์ถ๊ฐ๋ ํ ์ด ๋ชฉ๋ก์ ๋ฃจํ ์ธ๋ถ์์ DML ํธ์ถ์ ์ํํฉ๋๋ค. ์ด ํจํด์ ์
๋ฐ์ดํธ๋๋ sObject์ ๊ฐ์์ ๊ด๊ณ์์ด ํ๋์ DML ํธ์ถ๋ง ์ฌ์ฉํฉ๋๋ค.
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;
}์คํ ์ค์ธ ๋๋ ๋์์ธ ํจํด: ๊ด๋ จ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํ ์์
๊ณ์ ๊ด๋ จ ๊ธฐํ์ ์ก์ธ์คํ๋ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์์ฑํ์ฌ ํ์ตํ ๋์์ธ ํจํด์ ์ ์ฉํด ๋ณด๊ฒ ์ต๋๋ค. ์ด์ ์ ๋์์ AddRelatedRecord ํธ๋ฆฌ๊ฑฐ์ ๋ํ ํธ๋ฆฌ๊ฑฐ ์์ ๋ฅผ ์์ ํฉ๋๋ค. AddRelatedRecord ํธ๋ฆฌ๊ฑฐ๋ ๋๋์ผ๋ก ์๋ํ์ง๋ง ์ด์ ์ ๋์ ํธ๋ฆฌ๊ฑฐ๋ Trigger.New sObject ๋ ์ฝ๋๋ฅผ ๋ชจ๋ ๋ฐ๋ณตํ๋ฏ๋ก ๊ฐ๋ฅํ ํ ํจ์จ์ ์ด์ง ์์ต๋๋ค. ๋ค์ ์์ ์์๋ ๊ด์ฌ์๋ ๋ ์ฝ๋๋ง ๊ฐ์ ธ์จ ๋ค์ ํด๋น ๋ ์ฝ๋๋ฅผ ๋ฐ๋ณตํ๋๋ก ํธ๋ฆฌ๊ฑฐ ์ฝ๋์ SOQL ์ฟผ๋ฆฌ๋ฅผ ๋ชจ๋ ์์ ํฉ๋๋ค. ์ด ํธ๋ฆฌ๊ฑฐ๋ฅผ ์์ฑํ์ง ์์ ๊ฒฝ์ฐ๋ผ๋ ๊ฑฑ์ ํ์ง ์์ผ์
๋ ๋ฉ๋๋ค. ์ด ์น์
์์ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
AddRelatedRecord ํธ๋ฆฌ๊ฑฐ์ ๋ํ ์๊ตฌ ์ฌํญ์ ๊ฒํ ํด๋ณด๊ฒ ์ต๋๋ค. ํธ๋ฆฌ๊ฑฐ๋ ๊ณ์ ์ด ์ฝ์
๋๊ฑฐ๋ ์
๋ฐ์ดํธ๋ ํ์ ์คํ๋ฉ๋๋ค. ํธ๋ฆฌ๊ฑฐ๋ ์์ง ๊ธฐํ๊ฐ ์๋ ๋ชจ๋ ๊ณ์ ์ ๋ํด ๊ธฐ๋ณธ ๊ธฐํ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
๋จผ์ ์๋ก ์ฝ์
๋ ๊ณ์ ์๋ ๊ธฐ๋ณธ ๊ธฐํ๊ฐ ์์ผ๋ฏ๋ก ๊ณ์ ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ํ์ง๋ง ์
๋ฐ์ดํธ๋ ๊ณ์ ์ ๊ฒฝ์ฐ ๊ด๋ จ๋ ๊ธฐํ๊ฐ ์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ์ด์ Trigger.operationType ์ปจํ
์คํธ ๋ณ์์ switch ๋ฌธ์ ์ฌ์ฉํ์ฌ ์ฝ์
๊ณผ ์
๋ฐ์ดํธ ์์
์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๊ตฌ๋ถํด ๋ณด๊ฒ ์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ toProcess ๋ณ์๋ก ์ฒ๋ฆฌํด์ผ ํ๋ ๊ณ์ ์ ์ถ์ ํฉ๋๋ค. ๋ค์์ ์๋ฅผ ํ์ธํด ๋ณด์ธ์.
List<Account> toProcess = null;
switch on Trigger.operationType {
when AFTER_INSERT {
// do stuff
}
when AFTER_UPDATE {
// do stuff
}
}๋ชจ๋ ๊ณ์ ์ฝ์
์ ๊ฒฝ์ฐ ์ ๊ณ์ ์ toProcess ๋ชฉ๋ก์ ํ ๋นํ๋ฉด ๋ฉ๋๋ค.
when AFTER_INSERT {
ย ย ย ย ย toProcess = Trigger.New;
}์
๋ฐ์ดํธํ๋ ค๋ฉด ์ด ํธ๋ฆฌ๊ฑฐ์ ๊ธฐ์กด ๊ณ์ ์ ๊ด๋ จ ๊ธฐํ๊ฐ ์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ์ด ํธ๋ฆฌ๊ฑฐ๋ after ํธ๋ฆฌ๊ฑฐ์ด๋ฏ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํฅ์ ๋ฐ๋ ๋ ์ฝ๋๋ฅผ ์ฟผ๋ฆฌํ ์ ์์ต๋๋ค. ๋ค์์ toProcess ๋ชฉ๋ก์ ํ ๋นํ๋ SOQL ๋ฌธ์
๋๋ค.
when AFTER_UPDATE {
ย ย ย ย ย toProcess = [SELECT Id,Name FROM Account
ย ย ย ย ย ย ย ย ย ย ย WHERE Id IN :Trigger.New AND
ย ย ย ย ย ย ย ย ย ย ย Id NOT IN (SELECT AccountId FROM Opportunity WHERE AccountId in :Trigger.New)];
}์ด์ for ๋ฃจํ๋ฅผ ์ฌ์ฉํ์ฌ toProcess ๊ณ์ ๋ชฉ๋ก์ ๋ฐ๋ณตํ๊ณ oppList์ ๊ด๋ จ ๊ธฐ๋ณธ ๊ธฐํ๋ฅผ ์ถ๊ฐํฉ๋๋ค. ์๋ฃ๋๋ฉด insert DML ๋ฌธ์ ์ฌ์ฉํ์ฌ ๊ธฐํ ๋ชฉ๋ก์ ์ผ๊ด ์ถ๊ฐํฉ๋๋ค. ์ ์ฒด ํธ๋ฆฌ๊ฑฐ๋ฅผ ์์ฑํ๊ฑฐ๋ ์
๋ฐ์ดํธํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์ด๋ฏธ ์ด์ ์ ๋์
AddRelatedRecordํธ๋ฆฌ๊ฑฐ๋ฅผ ์์ฑํ ๊ฒฝ์ฐ ํด๋น ๋ด์ฉ์ ๋ค์ ํธ๋ฆฌ๊ฑฐ๋ก ๋ณ๊ฒฝํ์ฌ ํด๋น ํธ๋ฆฌ๊ฑฐ๋ฅผ ์์ ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ Developer Console์ ์ฌ์ฉํ์ฌ ๋ค์ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ถ๊ฐํ๊ณ ํธ๋ฆฌ๊ฑฐ ์ด๋ฆ์AddRelatedRecord๋ฅผ ์ ๋ ฅํฉ๋๋ค.
trigger AddRelatedRecord on Account(after insert, after update) {
List<Opportunity> oppList = new List<Opportunity>();
// Add an opportunity for each account if it doesn't already have one.
// Iterate over accounts that are in this trigger but that don't have opportunities.
List<Account> toProcess = null;
switch on Trigger.operationType {
when AFTER_INSERT {
// All inserted Accounts will need the Opportunity, so there is no need to perform the query
toProcess = Trigger.New;
}
when AFTER_UPDATE {
toProcess = [SELECT Id,Name FROM Account
WHERE Id IN :Trigger.New AND
Id NOT IN (SELECT AccountId FROM Opportunity WHERE AccountId in :Trigger.New)];
}
}
for (Account a : toProcess) {
// Add a default opportunity for this account
oppList.add(new Opportunity(Name=a.Name + ' Opportunity',
StageName='Prospecting',
CloseDate=System.today().addMonths(1),
AccountId=a.Id));
}
if (oppList.size() > 0) {
insert oppList;
}
}- ํธ๋ฆฌ๊ฑฐ๋ฅผ ํ
์คํธํ๋ ค๋ฉด Salesforce ์ฌ์ฉ์ ์ธํฐํ์ด์ค์์ ๊ณ์ ์ ๋ง๋ค๊ณ
Lions and Cats(์ฌ์ ๋ฐ ๊ณ ์์ด)๋ก ์ด๋ฆ์ ์ง์ ํฉ๋๋ค. - ๊ณ์ ํ์ด์ง์ ๊ธฐํ ๊ด๋ จ ๋ชฉ๋ก์์ ์ ๊ธฐํ
Lions and Cats(์ฌ์ ๋ฐ ๊ณ ์์ด)๋ฅผ ์ฐพ์ต๋๋ค. ํธ๋ฆฌ๊ฑฐ๊ฐ ๊ธฐํ๋ฅผ ์๋์ผ๋ก ์ถ๊ฐํ์ต๋๋ค.
๋ฆฌ์์ค
