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문에 전달
한번에 여러 sObject 처리 가능 → 거버너 제한 효율적 사용
List<Contact> conList = new List<Contact>{
new Contact(FirstName='Joe', LastName='Smith'),
new Contact(FirstName='Kathy', LastName='Smith')
};
insert conList; // 한번에 insert
insert + update 동시 처리 (기존 레코드가 있는지 먼저 확인 → 있으면 update, 없으면 insert)
ID, 외부 ID, idLookup 가능한 필드로 기존 레코드와 비교 후 삽입 또는 수정
upsert contactList;
upsert contactList Contact.fields.Email;
➡️ Contact의 Email 기준으로 Upsert (이메일 중복 체크하면서 삽입, 수정 가능)
insert, update, delete 같은 DML문 수행 중에 오류 발생할 수 있음. ⚠️DmlException
예를 들어:
필수 필드가 비어 있을 때
중복된 외부 ID가 들어왔을 때
잘못된 값이 들어왔을 때
→ 이때 코드를 그냥 놔두면 프로그램 전체가 중단되므로 반드시 예외를 잡아줘야 함
try {
Account acct = new Account();
// DML문 실행
insert acct;
} catch (DmlException e) {
// 예외 발생 시 실행 됨
System.debug(e.getMessage());
}
보통 우리는 이렇게 DML을 쓴다:
insert myAccount;
근데 이렇게 쓰면, 한 레코드라도 오류나면 바로 DmlException이 발생해서 전체 코드가 멈춘다.
이게 문제일 때가 많음.
👉 이걸 좀 더 "유연하게" 처리해주는 게 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;
이게 바로 Salesforce가 강력한 이유 중 하나
👉 부모 레코드를 삭제하면, 자식 레코드도 자동으로 삭제됨.
// SFDC Account 삭제
delete acct;
➡️ Account 레코드 삭제, 해당 Account에 연결된 모든 Contact도 같이 삭제
이걸 계단식 삭제 (Cascade Delete) 라고 부른다.
이게 항상 가능한 건 아니고 → Master-Detail 관계일 때 완전 보장
Lookup 관계에서는 "Delete this record also" 옵션을 켜줘야 자동 삭제됨
✅ 한 문장 요약
부모 ID를 자식 레코드에 넣으면 관계 생성, 부모 삭제 시 자식도 함께 삭제된다 (Cascade Delete).