- Salesforce 개체에 대한 트리거를 작성할 수 있습니다.
- 트리거 컨텍스트 변수를 사용할 수 있습니다.
- 트리거에서 클래스 메서드를 호출할 수 있습니다.
- 트리거의 sObject addError() 매서드를 사용하여 저장 작업을 제한할 수 있습니다.
Apex 트리거 작성
일반적으로 트리거를 사용하여 특정 조건에 따라 작업을 수행하거나 관련 레코드를 수정하거나 특정 작업이 발생하지 않도록 제한합니다. 트리거를 사용하여 SOQL 및 DML 실행 또는 사용자 정의 Apex 메서드 호출을 포함하여 Apex에서 할 수 있는 모든 작업을 수행할 수 있습니다.
트리거를 사용하여 Salesforce 사용자 인터페이스에서 포인트 앤 클릭 도구로 수행 불가능한 작업을 수행할 수 있습니다. 예를 들어 필드 값의 유효성을 검사하거나 레코드의 필드를 업데이트하는 경우 유효성 검사 규칙과 워크플로 규칙을 대신 사용합니다.
계정 또는 연락처와 같은 최상위 표준 개체, 사용자 정의 개체 및 일부 표준 하위 개체에 대해 트리거를 정의할 수 있습니다. 트리거는 생성 시 기본적으로 활성화됩니다. Salesforce는 지정된 데이터베이스 이벤트가 발생할 때 자동으로 활성 트리거를 실행합니다.
트리거 구문
trigger TriggerName on ObjectName (trigger_events) {
code_block
}
- 삽입 전
- 업데이트 전
- 삭제 전
- 삽입 후
- 업데이트 후
- 삭제 후
- 삭제 취소 후
예
- Developer Console에서 File(파일) | New(새로 만들기) | Apex Trigger(Apex 트리거)를 클릭합니다.
- 트리거 이름에 HelloWorldTrigger를 입력한 다음 sObject에 대한 Account(계정)를 선택합니다. Submit(제출)을 클릭합니다.
- 기본 코드를 다음으로 변경합니다.
trigger HelloWorldTrigger on Account (before insert) { System.debug('Hello World!'); }
Copy - 저장하려면 Ctrl+S를 누릅니다.
- 트리거를 테스트하려면 계정을 만듭니다.
- Debug(디버그) | Open Execute Anonymous Window(익명 실행 창 열기)를 클릭합니다.
- 새 창에서 다음을 추가한 다음 Execute(실행)를 클릭합니다.
Account a = new Account(Name='Test Trigger'); insert a;
Copy
- 디버그 로그에서 Hello World! 구문을 찾습니다. 또한 로그는 트리거가 실행되었음을 보여줍니다.
트리거 유형
트리거에는 두 가지 유형이 있습니다.
- Before triggers - 데이터베이스에 저장하기 전에 레코드 값을 업데이트하거나 유효성을 검사하는 데 사용됩니다.
- After triggers - 시스템에서 설정한 필드 값(예: 레코드의 ID 또는 LastModifiedDate 필드)에 액세스 및 다른 레코드의 변경 사항에 영향을 미치는 데 사용됩니다. after trigger가 발생한 레코드는 읽기 전용입니다.
컨텍스트 변수 사용
트리거를 발생한 레코드에 액세스하려면 컨텍스트 변수를 사용합니다. 예를 들어 Trigger.New에는 트리거 삽입 또는 업데이트에 삽입된 모든 레코드가 포함됩니다. Trigger.Old에서 트리거 업데이트에 업데이트되기 전의 sObject 이전 버전 또는 트리거 삭제에서 삭제된 sObject 목록을 제공합니다. 하나의 레코드가 삽입되거나 API 또는 Apex를 통해 많은 레코드가 대량으로 삽입될 경우 트리거가 발생할 수 있습니다. 따라서 Trigger.New와 같은 컨텍스트 변수에 하나의 레코드만 또는 여러 레코드를 포함할 수 있습니다. Trigger.New를 반복하여 각 개별 sObject를 가져올 수 있습니다.
이 예제는 HelloWorldTrigger 예시 트리거의 수정된 버전입니다. for 루프에서 각 계정을 반복하고 각각에 대한 설명 필드를 업데이트합니다.
trigger HelloWorldTrigger on Account (before insert) {
for(Account a : Trigger.New) {
a.Description = 'New description';
}
}
참고
시스템은 트리거 실행이 완료된 후 이전 트리거를 실행한 레코드를 저장합니다. DML 삽입 또는 업데이트 작업을 명시적으로 호출하지 않고 트리거의 레코드를 수정할 수 있습니다. 해당 레코드에 대해 DML 문을 수행하면 오류가 발생합니다.
일부 다른 컨텍스트 변수는 업데이트 또는 기타 이벤트로 인해 트리거가 실행되었는지 여부를 나타내는 부울 값을 반환합니다. 이러한 변수는 트리거가 여러 이벤트를 결합할 때 유용합니다. 예:
trigger ContextExampleTrigger on Account (before insert, after insert, after delete) {
if (Trigger.isInsert) {
if (Trigger.isBefore) {
// Process before insert
} else if (Trigger.isAfter) {
// Process after insert
}
}
else if (Trigger.isDelete) {
// Process after delete
}
}
컨텍스트 변수 트리거
다음 표는 트리거에 사용할 수 있는 모든 컨텍스트 변수의 포괄적인 목록입니다.
isExecuting | Apex 코드의 현재 컨텍스트가 Visualforce 페이지, 웹 서비스 또는 executeanonymous() API 호출이 아닌 트리거인 경우 true를 반환합니다. |
isInsert | Salesforce 사용자 인터페이스, Apex 또는 API에서 삽입 작업으로 인해 이 트리거가 실행된 경우 true를 반환합니다. |
isUpdate | Salesforce 사용자 인터페이스, Apex 또는 API에서 업데이트 작업으로 인해 이 트리거가 실행된 경우 true를 반환합니다. |
isDelete | Salesforce 사용자 인터페이스, Apex 또는 API에서 삭제 작업으로 인해 이 트리거가 실행된 경우 true를 반환합니다. |
isBefore | 레코드가 저장되기 전에 이 트리거가 실행된 경우 true를 반환합니다. |
isAfter | 모든 레코드가 저장된 후에 이 트리거가 실행된 경우 true를 반환합니다. |
isUndelete | Recycle Bin(휴지통)에서 레코드를 복구한 후 이 트리거가 실행된 경우 true를 반환합니다. 이 복구는 Salesforce 사용자 인터페이스, Apex 또는 API에서 삭제 취소 작업 후에 발생할 수 있습니다. |
new | sObject 레코드의 새 버전 목록을 반환합니다.이 sObject 목록은 insert, update 및 undelete 트리거에서만 사용할 수 있으며 레코드는 트리거 전에 수정만 할 수 있습니다. |
newMap | sObject 레코드의 새 버전에 대한 ID 지도입니다.이 지도는 before update, after insert, after update 및 after undelete 트리거에서만 사용할 수 있습니다. |
old | sObject 레코드의 이전 버전 목록을 반환합니다.이 sObject 목록은 update and delete 트리거에서만 사용할 수 있습니다. |
oldMap | sObject 레코드의 이전 버전에 대한 ID 지도입니다.이 지도는 update 및 delete 트리거에서만 사용할 수 있습니다. |
operationType | 현재 작업에 해당하는 System.TriggerOperation 유형의 열거형을 반환합니다.System.TriggerOperation 열거형의 가능한 값은 다음과 같습니다. BEFORE_INSERT, BEFORE_UPDATE, BEFORE_DELETE,AFTER_INSERT, AFTER_UPDATE, AFTER_DELETE 및 AFTER_UNDELETE 다양한 트리거 유형에 따라 프로그래밍 논리를 변경하는 경우 고유한 트리거 실행 열거 상태의 순열이 다른 switch 문을 사용해 보세요. |
size | 이전 및 새 트리거 호출의 총 레코드 수입니다. |
트리거에서 클래스 메서드 호출
트리거에서 공용 유틸리티 메서드를 호출할 수 있습니다. 다른 클래스의 메서드를 호출하면 코드 재사용이 가능하고 트리거 크기가 줄어들며 Apex 코드의 유지 관리가 향상됩니다. 또한 개체 지향 프로그래밍을 사용할 수 있습니다.
다음 예제 트리거는 트리거에서 정적 메서드를 호출하는 방법을 보여줍니다. 삽입 이벤트로 인해 트리거가 실행된 경우 예제에서 EmailManager 클래스에 대한 정적 sendMail() 메서드를 호출합니다. 이 유틸리티 메서드는 지정된 수신자에게 이메일을 보내고 삽입된 연락처 레코드 수를 포함합니다.
참고
EmailManager 클래스는 Apex 시작하기 유닛의 클래스 예제에 포함되어 있습니다. 이 트리거를 저장하기 전에 조직의 EmailManager 클래스를 저장하고 sendMail() 메서드를 정적으로 변경합니다.
- Developer Console에서 File(파일) | New(새로 만들기) | Apex Trigger(Apex 트리거)를 클릭합니다.
- 트리거 이름에 ExampleTrigger를 입력한 다음 sObject에 대한 Contact(연락처)를 선택합니다. Submit(제출)을 클릭합니다.
- 기본 코드를 다음으로 바꾼 다음 sendMail()의 이메일 주소 자리 표시자 텍스트를 이메일 주소로 수정합니다.
trigger ExampleTrigger on Contact (after insert, after delete) { if (Trigger.isInsert) { Integer recordCount = Trigger.New.size(); // Call a utility method from another class EmailManager.sendMail('Your email address', 'Trailhead Trigger Tutorial', recordCount + ' contact(s) were inserted.'); } else if (Trigger.isDelete) { // Process after delete } }
Copy - 저장하려면 Ctrl+S를 누릅니다.
- 트리거를 테스트하려면 연락처를 만듭니다.
- Debug(디버그) | Open Execute Anonymous Window(익명 실행 창 열기)를 클릭합니다.
- 새 창에서 다음을 추가한 다음 Execute(실행)를 클릭합니다.
Contact c = new Contact(LastName='Test Contact'); insert c;
Copy
- 디버그 로그에서 트리거가 실행되었는지 확인합니다. 로그 끝 부분에서 유틸리티 메서드(DEBUG|Email sent successfully)로 작성된 디버그 메시지를 찾습니다.
- 이제 본문 텍스트 1개의 연락처가 삽입되었습니다.가 포함된 이메일을 받았는지 확인합니다.새 트리거가 있으면 연락처를 하나 이상 추가할 때마다 이메일을 받게 됩니다.
관련 레코드 추가
트리거는 종종 트리거 컨텍스트의 레코드(이 트리거를 발생시킨 레코드)와 관련된 레코드에 액세스하고 관리하는 데 사용됩니다.
이 트리거는 기회가 이미 계정과 연결되어 있지 않은 경우 새 계정 또는 업데이트된 각 계정에 대한 관련 기회를 추가합니다. 트리거는 먼저 SOQL 쿼리를 수행하여 트리거가 실행된 계정에 대한 모든 하위 기회를 가져옵니다. 다음으로 트리거는 Trigger.New의 sObject 목록을 반복하여 각 계정 sObject를 가져옵니다. 계정에 관련된 기회 sObject가 없는 경우 for 루프는 기회를 만듭니다. 트리거가 새로운 기회를 생성한 경우 최종 명령문이 이를 삽입합니다.
- Developer Console을 사용하여 다음 트리거를 추가합니다(HelloWorldTrigger 예제의 단계를 따르지만 트리거 이름에 대해 AddRelatedRecord를 사용합니다).
trigger AddRelatedRecord on Account(after insert, after update) { List<Opportunity> oppList = new List<Opportunity>(); // Get the related opportunities for the accounts in this trigger Map<Id,Account> acctsWithOpps = new Map<Id,Account>( [SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.New]); // Add an opportunity for each account if it doesn't already have one. // Iterate through each account. for(Account a : Trigger.New) { System.debug('acctsWithOpps.get(a.Id).Opportunities.size()=' + acctsWithOpps.get(a.Id).Opportunities.size()); // Check if the account already has a related opportunity. if (acctsWithOpps.get(a.Id).Opportunities.size() == 0) { // If it doesn't, add a default opportunity oppList.add(new Opportunity(Name=a.Name + ' Opportunity', StageName='Prospecting', CloseDate=System.today().addMonths(1), AccountId=a.Id)); } } if (oppList.size() > 0) { insert oppList; } }
Copy - 트리거를 테스트하려면 Salesforce 사용자 인터페이스에서 계정을 만들고 Apple & Oranges 이름을 지정합니다.
- 계정 페이지의 기회 관련 목록에서 새 기회를 찾습니다. 트리거가 이 기회를 자동으로 추가했습니다.
추가 기본 정보
추가한 트리거는 트리거 컨텍스트의 일부인 모든 레코드, 즉 Trigger.New를 반복하는 for 루프를 반복합니다. 그러나 이 트리거의 루프가 더 효율적일 수 있습니다. 이 트리거 컨텍스트에서 모든 계정에 실제로 액세스할 필요는 없지만 하위 집합, 즉 기회가 없는 계정에만 액세스할 필요가 있습니다. 다음 유닛에서는 이 트리거를 보다 효율적으로 만드는 방법을 보여줍니다. 대량 트리거 디자인 패턴 유닛에서 기회가 없는 계정만 가져오도록 SOQL 쿼리를 수정하는 방법을 알아봅니다. 그런 다음 해당 레코드에 대해서만 반복하는 방법을 배웁니다.
트리거 예외 사용
특정 조건이 충족되면 레코드가 저장되지 않도록 하는 것과 같이 특정 데이터베이스 작업에 대한 제한을 추가해야 하는 경우가 있습니다. 트리거에 레코드가 저장되지 않도록 하려면 문제가 되는 sObject에 대한 addError() 메서드를 호출합니다. addError() 메서드는 트리거 내부에서 치명적인 오류를 발생시킵니다. 오류 메시지는 사용자 인터페이스에 표시되고 기록됩니다.
다음 트리거는 관련 기회가 있는 경우 계정이 삭제되는 것을 방지합니다. 기본적으로 계정을 삭제하면 모든 관련 레코드가 계단식으로 삭제됩니다. 이 트리거는 기회의 계단식 삭제를 방지합니다. 이 트리거를 직접 사용해 보세요. 이전 예제를 실행한 경우 조직에 관련 기회가 있는 Apples & Oranges라는 계정이 있습니다. 이 예제에서 해당 샘플 계정을 사용합니다.
- Developer Console을 사용하여 다음 트리거를 추가합니다.
trigger AccountDeletion on Account (before delete) { // Prevent the deletion of accounts if they have related opportunities. for (Account a : [SELECT Id FROM Account WHERE Id IN (SELECT AccountId FROM Opportunity) AND Id IN :Trigger.old]) { Trigger.oldMap.get(a.Id).addError( 'Cannot delete account with related opportunities.'); } }
Copy - Salesforce 사용자 인터페이스에서 Apples & Oranges 계정 페이지로 이동하여 Delete(삭제)를 클릭합니다.
- 확인 팝업에서 OK(확인)를 클릭합니다.Cannot delete account with related opportunities(관련 기회가 있는 계정을 삭제할 수 없습니다.). 사용자 정의 오류 메시지로 유효성 검사 오류를 찾습니다.
- AccountDeletion 트리거를 비활성화합니다. 이 트리거를 활성 상태로 두면 과제를 확인할 수 없습니다.
- Setup(설정)에서 Apex Triggers(Apex 트리거)를 검색합니다.
- Apex 트리거 페이지에서 AccountDeletion 트리거 옆에 있는 Edit(편집)을 클릭합니다.
- Is Active(활성)를 선택 해제합니다.
- Save(저장)를 클릭합니다.
추가 기본 정보
트리거에서 addError()를 호출하면 대량 DML이 부분적으로 성공하여 호출된 경우를 제외하고 전체 작업 집합이 롤백되도록 합니다.
- Apex의 DML 문이 트리거를 생성한 경우 모든 오류가 전체 작업을 롤백합니다. 그러나 런타임 엔진은 여전히 작업의 모든 레코드를 처리하여 포괄적인 오류 목록을 컴파일합니다.
- Lightning Platform API의 대량 DML 호출이 트리거를 생성한 경우 런타임 엔진이 잘못된 레코드를 따로 설정합니다. 그런 다음 런타임 엔진은 오류를 생성하지 않은 레코드를 부분적으로 저장해 봅니다.
트리거 및 콜아웃
Apex를 사용하면 외부 웹 서비스를 호출하고 Apex 코드를 외부 웹 서비스와 통합할 수 있습니다. 외부 웹 서비스에 대한 Apex 호출을 콜아웃이라고 합니다. 예를 들어 주식 시세 서비스에 콜아웃을 만들어 최신 시세를 얻을 수 있습니다. 트리거에서 콜아웃을 만들 경우 외부 서비스의 응답을 기다리는 동안 트리거 프로세스가 작업을 차단하지 않도록 콜아웃을 비동기적으로 수행해야 합니다. 비동기 콜아웃은 백그라운드 프로세스에서 이루어지며 응답은 외부 서비스가 이를 반환합니다.
트리거에서 콜아웃을 만들려면 비동기적으로 실행되는 클래스 메서드를 호출합니다. 이러한 메서드를 future 메서드라고 하며 @future(callout=true) 주석을 추가합니다. 이 예제 클래스에는 콜아웃을 만드는 future 메서드가 포함되어 있습니다.
참고
이 예제에서는 설명 목적으로만 가상의 끝점 URL을 사용합니다. 끝점을 유효한 URL로 변경하고 끝점에 대해 Salesforce에 원격 사이트를 추가하지 않으면 이 예제를 실행할 수 없습니다.
public class CalloutClass {
@future(callout=true)
public static void makeCallout() {
HttpRequest request = new HttpRequest();
// Set the endpoint URL.
String endpoint = 'http://yourHost/yourService';
request.setEndPoint(endpoint);
// Set the HTTP verb to GET.
request.setMethod('GET');
// Send the HTTP request and get the response.
HttpResponse response = new HTTP().send(request);
}
}
trigger CalloutTrigger on Account (before insert, before update) {
CalloutClass.makeCallout();
}
Custom Metadata Types
'개발자정보' 카테고리의 다른 글
IT 항해를 위한 한마디 (0) | 2022.03.13 |
---|---|
시스템이 작동하는 시간에서 고장이나 보수 등으로 사용하지 못한 시간을 제외한 전체 작동 시간을 계산하기 위한 오픈 전 테스트 (0) | 2022.03.13 |
Salesforce FIND , 문자열 검색 방법 (0) | 2022.03.02 |
나의 Salesforce 성능 테스트 방법 (0) | 2022.02.13 |
Salesforce Instances 상태 확인하는 방법 (0) | 2022.02.13 |