어느 Salesforce Developer의 개발 성장기

Salesforce Apex - DML Statement와 Database Method 본문

Salesforce/Learning concept

Salesforce Apex - DML Statement와 Database Method

Developer_Foryou 2020. 3. 12. 03:05

DML Statement

  • DML Statement는 single sObject 또는 a list (or array) of sObjects를 허용한다.
  • Salesforce에 있는 특별한 DML 문
    • upsert : 지정된 필드를 사용하여 기존 개체의 존재 여부를 결정하거나 필드가 지정되지 않은 경우 ID 필드를 사용하여 단일 레코드 내에서 sObject 레코드를 새로 작성하고 업데이트한다
      (→ 기존 레코드가 있으면 Update / 레코드가 없으면 Insert)
    • merge : 동일한 sObject 유형의 최대 세 개의 레코드를 레코드 중 하나에 병합하고, 다른 레코드를 삭제하고, 관련된 모든 레코드를 다시 연결한다.
  • bulk DML operation Limits: Apex transaction 당 DML 제한 150문
    • bulk DML operation 을 장려하는 이유
      • List<sObject>에서 DML 작업을 수행하면 각 sObject에 대해 하나의 명령문이 아닌 하나의DML문으로 계산한다.
    * // Create a list of contacts
        List<Contact> conList = new List<Contact> {
            new Contact(FirstName='Joe',LastName='Smith',Department='Finance'),
            new Contact(FirstName='Kathy',LastName='Smith',Department='Technology'),
            new Contact(FirstName='Caroline',LastName='Roth',Department='Finance'),
            new Contact(FirstName='Kim',LastName='Shain',Department='Education')};
                    
        // Bulk insert all contacts with one DML call
        insert conList;
        
        // List to hold the new contacts to update
        List<Contact> listToUpdate = new List<Contact>();
        // Iterate through the list and add a title only
        //   if the department is Finance
        for(Contact con : conList) {
            if (con.Department == 'Finance') {
                con.Title = 'Financial analyst';
                // Add updated contact sObject to the list.
                listToUpdate.add(con);
            }
        }
        // Bulk update all contacts with one DML call
        update listToUpdate;
  • Upsert Record : List에 새로운 레코드와 존재하는 레코드가 혼재되어 섞여있을 때 사용. (Insert + Update)
    • 레코드 중복 방지
    • 시간 단축 (추가하려는 레코드가 이미 존재하는지 확인할 시간이 필요없다.)
// Example 1
upsert sObjectList Account.Fields.MyExternalId;

// Example 2
// Insert the Josh contact
Contact josh = new Contact(FirstName='Josh',LastName='Kaplan',Department='Finance');       
insert josh;
// Josh's record has been inserted
//   so the variable josh has now an ID
//   which will be used to match the records by upsert
josh.Description = 'Josh\'s record has been updated by the upsert operation.';
// Create the Kathy contact, but don't persist it in the database
Contact kathy = new Contact(FirstName='Kathy',LastName='Brown',Department='Technology');
// List to hold the new contacts to upsert
List<Contact> contacts = new List<Contact> { josh, kathy };
// Call upsert
upsert contacts;
// Result: Josh is updated and Kathy is created.

//	Example 3
Contact jane = new Contact(FirstName='Jane',
							LastName='Smith',
                            Email='jane.smith@example.com',
                            Description='Contact of the day');
insert jane;
// 1. Upsert using an Lookup field
// Create a second sObject variable.
// This variable doesn’t have any ID set.
Contact jane2 = new Contact(FirstName='Jane',
							LastName='Smith',  
							Email='jane.smith@example.com',
							Description='Prefers to be contacted by email.');
// Upsert the contact by using the idLookup field for matching.
upsert jane2 Contact.fields.Email;

// Verify that the contact has been updated
System.assertEquals('Prefers to be contacted by email.',
[SELECT Description FROM Contact WHERE Id=:jane.Id].Description);
  • Delete Record : 레코드 삭제
    • ex)
    • Contact[] contactsDel = [SELECT Id FROM Contact WHERE LastName='Smith'];
    • delete contactsDel;
  • DML Statement Exceptions 방지
    • DML operation이 실패할 경우, return값으로 DmlException을 반환.
try {
	// This causes an exception because 
	//   the required Name field is not provided.
	Account acct = new Account();
	// Insert the account 
	insert acct;
} catch (DmlException e) {
	System.debug('A DML exception has occurred: ' +
	e.getMessage());
}

 

Database Methods

  • Database method는 class 이름으로 호출
  • static 이다.
  • 작업을 부분적으로 성공시킬지 여부를 지정할 수 있다. (파라미터 : allOrNone)
    • 기본값 : true
    • false
      • 부분 레코드 집합에 오류가 발생하면 성공적인 레코드가 커밋되고 실패한 레코드에 대한 오류가 반환된다.
      • 부분 성공 옵션과 함께 예외가 발생하지 않는다.
  • Database method는 성공 여부를 저장하는 배열로 반환한다.
    • Database.SaveResult[] results = Database.insert(recordList, false);
// ex) Contact에 Last name(필수 필드)을 안넣었을 때와 같은 오류를 찾을 때, err 메세지 출력	
// Create a list of contacts
List<Contact> conList = new List<Contact> {
                        new Contact(FirstName='Joe',LastName='Smith',Department='Finance'),
                        new Contact(FirstName='Kathy',LastName='Smith',Department='Technology'),
                        new Contact(FirstName='Caroline',LastName='Roth',Department='Finance'),
                        new Contact()};

// Bulk insert all contacts with one DML call
Database.SaveResult[] srList = Database.insert(conList, false);

// Iterate through each returned result
for (Database.SaveResult sr : srList) {
	if (sr.isSuccess()) {
		// Operation was successful, so get the ID of the record that was processed
		System.debug('Successfully inserted contact. Contact ID: ' + sr.getId());
	} else {
    	// Operation failed, so get all errors
		for(Database.Error err : sr.getErrors()) {
        	System.debug('The following error has occurred.');
			System.debug(err.getStatusCode() + ': ' + err.getMessage());
			System.debug('Contact fields that affected this error: ' + err.getFields());
		}
	}
}

 

언제 DML Statement 와 Database Methods 사용하는가?

  • DML Statement
    • bulk DML operation 중에 발생하는 오류를 try-catch를 통해 즉시 DmlException으로 중단시키는 경우
  • Database Methods
    • DmlException을 무시할 경우
    • 실패한 것을 무시하고 모두 진행시킨 뒤, 실패한 것만 따로 처리하려고 할 때
    • Note : Database methods에서도 exception을 발생시킬 수 있다.
Comments