💡 SOQL 쿼리란?
SOQL은 Salesforce Object Query Language의 약자!
SOQL을 사용해 조직의 데이터베이스에 저장되어 있는 정보를 읽을 수 있다.
세일즈포스는 SOQL을 이용해서 SQL의 기능을 한다.
SOQL의 구문은 SQL(Structured Query Language)과 유사하지만
그렇다고 SOQL이 SQL은 아니다.
사용할 때 주의!
단일 sObject에도 사용할 수 있긴하지만
System.QueryException: List has no rows for assignment to SObject
이 나타날 것이다.
쿼리가 실행될 때마다 단일 sObject가 반환된다는 것을 보장할 수 없는 경우 쿼리를 sObject 목록에 할당해야 함!
Player__c player = [SELECT Id from Player__c where Name = :username];
if (player != null)
p = player.Id;
일치하는 사용자 이름을 가진 Player__c 레코드가 없으면 위의 코드는 실패!
그렇기 때문에
Player__c[] players = [SELECT Id from Player__c where Name = :username];
if (players.size() > 0)
p = players[0].Id;
이렇게 적는게 더 안전하다.
단일쿼리 조회
public with sharing class SOQLQueriesInApex {
public static List<Contact> searchForContacts(Id inputSearch) {
// //0032w00000yTR43AAG
List<Contact> contacts = [SELECT FirstName, LastName FROM Contact WHERE Id = :inputSearch];
System.debug(contacts);
return contacts;
}
}
여러 쿼리 조회
public with sharing class SOQLSearchMultipleQueries {
public static List<Contact> searchForContacts() {
List<Contact> Contacts = [SELECT Id From Contact];
System.debug('총' + Contacts.size());
for (Contact c : Contacts) {
System.debug(c);
}
return Contacts;
}
}
Heap 크기 초과 방지하기 위한 방지
200개까지 가능!!!!
for (List<Contact> Contacts : [SELECT Id From Contact]) {
System.debug(Contacts);
System.debug('총' + Contacts.size());
}
-> 이렇게 쓰면 만약 220개 목록 반환한다면
첫번째 라인 200, 두번째 라인 20개
💡 일반 SQL과 차이점
- SELECT * 을 쓸 수 없다.
- 쿼리문만 지원한다( 일반 SOQL 처럼 스키마라든지, CRUD, 트랜잭션 등은 지원하지 않는다)
https://trailhead.salesforce.com/ko/content/learn/modules/apex_database/apex_database_soql
사용방법
💡모든 계정 조회하기
1. 일단 계정을 추가
Account acct = new Account(
Name='SFDC Computing',
Phone='(415)555-1212',
NumberOfEmployees=50,
BillingCity='San Francisco');
insert acct;
ID acctID = acct.ID;
Contact con = new Contact(
FirstName='Carol',
LastName='Ruiz',
Phone='(415)555-1212',
Department='Wingo',
AccountId=acctID); //acctID 여기에 넣겠다
insert con;
Account acct2 = new Account(
Name='The SFDC Query Man',
Phone='(310)555-1213',
NumberOfEmployees=50,
BillingCity='Los Angeles',
Description='Expert in wing technologies.');
insert acct2;
2.
click the Query Editor tab.
SELECT Name,Phone FROM Account
이러면 이제 조회가 가능해진다!
💡조건으로 쿼리 결과 필터링
예1 )이름이 SFDC Computing이고 직원이 25명 이상인 모든 계정
SELECT Name,Phone FROM Account WHERE (Name='SFDC Computing' AND NumberOfEmployees>25)
예2) 모든 SFDC 컴퓨팅 계정 + 청구 도시가 로스앤젤레스이고 직원이 25명 이상인 모든 계정
SELECT Name,Phone
FROM Account
WHERE (Name='SFDC Computing' OR (NumberOfEmployees>25 AND BillingCity='Los Angeles'))
💡반환되는 레코드 수 제한
Account oneAccountOnly = [SELECT Name,Phone FROM Account LIMIT 1];
-> 반환된 첫번째 계정을 검색
Limit 3이면 차례대로 3개 데이터만 보여주겠다.
SELECT 열명 FROM 테이블명 LIMIT 시작행, 개수
Limit 4, 4 -> 5 6 7 8
SELECT Name,Phone FROM Account
WHERE (Name = 'SFDC Computing' AND NumberOfEmployees>25)
ORDER BY Name
LIMIT 10
💡Apex에서 SOQL 쿼리 실행
Account[] accts = [SELECT Name,Phone FROM Account
WHERE (Name='SFDC Computing' AND NumberOfEmployees>25)
ORDER BY Name
LIMIT 10];
System.debug(accts.size() + ' account(s) returned.');
System.debug(accts);
💡SOQL 쿼리의 변수 액세스
Apex의 SOQL 문은 앞에 콜론(:)이 있는 경우 Apex 코드 변수 및 표현식을 참조할 수 있습니다. SOQL 문 내에서 지역 변수를 사용하는 것을 bind라고 합니다.
String targetDepartment = 'Wingo';
Contact[] techContacts = [SELECT FirstName,LastName
FROM Contact WHERE Department=:targetDepartment];
System.debug(techContacts);
Int a =1; 일때 데이터 타입은 int로 바인딩, a라는 변수명이 바인딩, 1이라는 값이 바인딩
실행 이전에 값이 확정되면 정적 바인딩
실행 이후에 값이 확정되면 동적 바인딩
데이터타입 int ->컴파일 할 때 메모리에 할당되므로 정적 바인딩
a변수명 또한 메모리에 할당되므로 정적바인딩
값 1은 실행시 할당되므로 동적바인딩이라고 한다.
자바는 메소드를 기본적으로 동적바인딩하기 때문에 메소드 오버라이딩이 가능
static또한 메모리를 한번밖에 할당하므로 컴파일시 메모리 할당 -> 정적 바인딩
정적바인딩 : 속도가 빨라서 효율적, 값이 변하지 않아 안정적
컴파일 시 이미값이 확정!
동적바인딩 : 값이 변할 수 있다. 들어올 값이 무엇인지 모르니 들어올 값보다 메모리공간을 차지하고 있어 메모리공간 낭비,,,,그래서 속도가 느려짐
SELECT Name, (SELECT LastName FROM Contacts)
FROM Account
WHERE Name = 'SFDC Computing'
💡sObject에서 연락처 관계 이름을 사용하여 SOQL 결과에서 하위 레코드를 가져오는 방법
Account[] acctsWithContacts = [SELECT Name, (SELECT FirstName,LastName FROM Contacts)
FROM Account
WHERE Name = 'SFDC Computing'];
// Get child records
Contact[] cts = acctsWithContacts[0].Contacts;
System.debug('Name of first associated contact: '
+ cts[0].FirstName + ', ' + cts[0].LastName);
이름이 Carol인 연락처 레코드를 쿼리하고 계정과 연락처 간의 관계를 탐색하여 Carol과 연결된 계정의 이름을 검색할 수 있습니다.
Contact[] cts = [SELECT Account.Name FROM Contact
WHERE FirstName = 'Carol' AND LastName='Ruiz'];
Contact carol = cts[0];
String acctName = carol.Account.Name;
System.debug('Carol\'s account name is ' + acctName);
💡 SOQL For Loops를 사용하여 일괄 레코드 쿼리
10000개가 넘는 레코드에서 하나의 작업을 실행하는 유일한 방법은 Batch Apex 클래스를 작성