DML로 레코드 조작하기

Isa.log·2025년 6월 23일

학습 목표

  • DML로 레코드 삽입, 수정, 삭제
  • 대량 DML 수행
  • upsert 사용법
  • DML 예외 처리
  • Database 메서드 활용
  • 관련 레코드 작업

DML문 기본

DML (Data Manipulation Language)

insert : 레코드 삽입
update : 레코드 수정
delete : 레코드 삭제
upsert : 삽입 or 수정 (ID나 외부 ID 기준)
undelete : 삭제 취소
merge : 중복된 레코드 병합

upsert 및 merge문은 Salesforce에만 해당되며 매우 편리

//Create the account sObject 
Account acct = new Account(Name='Acme', Phone='(415)555-1212', NumberOfEmployees=100);

//Insert the account by using DML
insert acct;

➡️ Acme 계정을 Salesforce에 추가하고 계정 sObject가 먼저 생성된 다음 인수를 Salesforce에서 레코드를 유지하는 문인 insert문에 전달

대량 DML (List 활용)

한번에 여러 sObject 처리 가능 → 거버너 제한 효율적 사용

List<Contact> conList = new List<Contact>{
    new Contact(FirstName='Joe', LastName='Smith'),
    new Contact(FirstName='Kathy', LastName='Smith')
};
insert conList;  // 한번에 insert

Upsert

insert + update 동시 처리 (기존 레코드가 있는지 먼저 확인 → 있으면 update, 없으면 insert)
ID, 외부 ID, idLookup 가능한 필드로 기존 레코드와 비교 후 삽입 또는 수정

upsert contactList;  
upsert contactList Contact.fields.Email;

➡️ Contact의 Email 기준으로 Upsert (이메일 중복 체크하면서 삽입, 수정 가능)

DML 예외 처리

왜 예외 처리가 필요한가?

insert, update, delete 같은 DML문 수행 중에 오류 발생할 수 있음. ⚠️DmlException

예를 들어:
필수 필드가 비어 있을 때
중복된 외부 ID가 들어왔을 때
잘못된 값이 들어왔을 때

→ 이때 코드를 그냥 놔두면 프로그램 전체가 중단되므로 반드시 예외를 잡아줘야 함

try-catch 사용하여 오류 핸들링

try {
    Account acct = new Account();
    
    // DML문 실행 
    insert acct;
    
} catch (DmlException e) {

	// 예외 발생 시 실행 됨 
    System.debug(e.getMessage());
}

Database 클래스 메서드

Database 클래스 메서드가 왜 필요하냐면

보통 우리는 이렇게 DML을 쓴다:

insert myAccount;

근데 이렇게 쓰면, 한 레코드라도 오류나면 바로 DmlException이 발생해서 전체 코드가 멈춘다.
이게 문제일 때가 많음.

👉 이걸 좀 더 "유연하게" 처리해주는 게 Database 클래스 메서드 !!

Database 클래스 메서드 사용하기

DML 문을 대신하여 사용 가능, 더 세부적인 성공·실패 제어

Database.insert()
Database.update()
Database.upsert()
Database.delete()

부분 성공 처리 가능 (allOrNone = false):

// 리스트 준비
List<Contact> conList = new List<Contact> {
    new Contact(FirstName='Joe', LastName='Smith'),
    new Contact(FirstName='Kathy', LastName='Smith'),
    new Contact()  // 필수 LastName 누락 → 실패 예정
};

// Database 클래스 사용, allOrNone = false
Database.SaveResult[] results = Database.insert(conList, false);

// 결과 확인
for (Database.SaveResult sr : results) {
    if (sr.isSuccess()) { 
        // 성공한 경우
        System.debug('성공: ' + sr.getId()); 
    } else {
        // 실패한 경우
        System.debug('실패: ' + sr.getErrors()[0].getMessage());
    }
}

관련 레코드 작업 (관계형 레코드)

Salesforce 데이터 구조에서 관계형 데이터 다루기의 핵심!

관계를 만드는 방법

Salesforce에서는 여러 개의 테이블(객체)이 서로 연결되어 있는 구조.

예를 들어:
Account (계정) → 상위 객체 (부모)
Contact (연락처) → 하위 객체 (자식)

한 Account에 여러 Contact가 연결될 수 있음.
이런 관계를 Parent-Child 관계 또는 Lookup / Master-Detail 관계라고 부름.

// ① 먼저 상위 객체(Account) 생성
Account acct = new Account(Name='SFDC Account');
insert acct;  // DB에 저장 → acct.Id 값이 자동으로 생성됨

// ② Contact를 만들면서 AccountId를 설정 (부모와 연결)
Contact mario = new Contact(
    FirstName='Mario', 
    LastName='Ruiz', 
    AccountId=acct.Id  // 관계 연결!
);
insert mario;

계단식 삭제 (Cascade Delete)

이게 바로 Salesforce가 강력한 이유 중 하나
👉 부모 레코드를 삭제하면, 자식 레코드도 자동으로 삭제됨.

// SFDC Account 삭제
delete acct;

➡️ Account 레코드 삭제, 해당 Account에 연결된 모든 Contact도 같이 삭제

이걸 계단식 삭제 (Cascade Delete) 라고 부른다.

이게 항상 가능한 건 아니고 → Master-Detail 관계일 때 완전 보장

Lookup 관계에서는 "Delete this record also" 옵션을 켜줘야 자동 삭제됨

✅ 한 문장 요약
부모 ID를 자식 레코드에 넣으면 관계 생성, 부모 삭제 시 자식도 함께 삭제된다 (Cascade Delete).

profile
세상을 탐험하던 눈으로, 지금은 디버깅 중

0개의 댓글