Salesforce 數(shù)據(jù)庫(kù)操作簡(jiǎn)介

Salesforce 中的數(shù)據(jù)庫(kù)操作方式

Salesforce 為用戶和開發(fā)者提供了四種基本的數(shù)據(jù)庫(kù)操作方式:

  • Apex 中的 DML 語(yǔ)句
  • Apex 中的 Database 類
  • SOQL 查詢
  • SOSL 查詢

DML 語(yǔ)句

DML 全稱 Data Manipulation Language膝擂,是 Apex 中直接進(jìn)行數(shù)據(jù)庫(kù)操作的一組命令弧可。和大多數(shù)數(shù)據(jù)庫(kù)類似,DML 語(yǔ)句包括:

  • insert,插入
  • update勘纯,更新
  • upsert假瞬,插入或更新
  • delete哥捕,刪除
  • undelete诚纸,撤銷刪除
  • merge,合并
    每個(gè)DML語(yǔ)句都可以對(duì)一個(gè)或多個(gè) sObject 對(duì)象進(jìn)行操作谷炸。Salesforce 鼓勵(lì)用戶使用同一條 DML 語(yǔ)句對(duì)多條數(shù)據(jù)進(jìn)行操作北专,而不是對(duì)每條數(shù)據(jù)分別調(diào)用一次相同的 DML 語(yǔ)句。這樣做可以優(yōu)化執(zhí)行效率旬陡。

upsert 語(yǔ)句特點(diǎn)

upsert 語(yǔ)句包括了 insert 和 update 的功能拓颓。對(duì)于將要進(jìn)行 upsert 操作的數(shù)據(jù),Salesforce 會(huì)檢索數(shù)據(jù)庫(kù)中這些數(shù)據(jù)是否已經(jīng)存在描孟。對(duì)于已經(jīng)存在的數(shù)據(jù)驶睦,進(jìn)行 update 處理,對(duì)于不存在的數(shù)據(jù)画拾,進(jìn)行 insert 處理啥繁。

需要注意的是,upsert 語(yǔ)句的執(zhí)行效率比 update 和 insert 都要低青抛,所以我們?cè)谶M(jìn)行開發(fā)的時(shí)候,要盡可能的避免使用 upsert 語(yǔ)句酬核。

merge 語(yǔ)句特點(diǎn)

merge 語(yǔ)句可以將至多三條相同類型的記錄合并蜜另,只保留一條數(shù)據(jù),刪除其他兩條嫡意,并將之前與三條記錄相關(guān)的其他數(shù)據(jù)記錄重新關(guān)聯(lián)到保留的記錄中举瑰。

系統(tǒng)內(nèi)的 ID 字段

對(duì)于每個(gè)對(duì)象,無(wú)論是標(biāo)準(zhǔn)的還是自定義的蔬螟,Salesforce 都會(huì)自動(dòng)創(chuàng)建一個(gè) ID 字段此迅。該字段的值是由系統(tǒng)自動(dòng)生成,在整個(gè)系統(tǒng)內(nèi)部唯一存在,并且不會(huì)更改耸序。

在用戶利用 DML 的 insert 或 upsert 語(yǔ)句插入新的數(shù)據(jù)記錄后忍些,便可以直接使用該記錄的 ID 字段。

Account acc = new Account(Name='test account');

insert acc;

ID accountId = acc.Id;

在上面的代碼中坎怪,變量 accountId 中存儲(chǔ)了剛剛建立的 Account 記錄的 ID 值罢坝。用戶可以立即利用該 ID 值進(jìn)行其他操作。

DML 語(yǔ)句操作示例

// 插入單條數(shù)據(jù)
Account acc = new Account(Name='test');
insert acc;

// 插入多條數(shù)據(jù)
List<Account> accList = new List<Account> {
    new Account(Name='test1'),
    new Account(Name='test2'),
    new Account(Name='test3'),
    new Account(Name='test4')
};
insert accList;

// 更新單條數(shù)據(jù)
acc.Name = 'test name';
update acc;

// 更新多條數(shù)據(jù)
for(Account a : accList) {
    a.Phone = '12345678';
}
update accList;

// 刪除單條數(shù)據(jù)
delete acc;

// 刪除多條數(shù)據(jù)
delete accList;

upsert 語(yǔ)句示例

upsert 語(yǔ)句運(yùn)行時(shí)搅窿,先比較數(shù)據(jù)中某個(gè)字段的值是否在數(shù)據(jù)庫(kù)中已經(jīng)存在嘁酿,如果存在則更新該數(shù)據(jù),否則插入該數(shù)據(jù)男应。

upsert 語(yǔ)句有兩個(gè)參數(shù)闹司,第一個(gè)參數(shù)是需要操作的單條數(shù)據(jù)或一組數(shù)據(jù),第二個(gè)參數(shù)是可選參數(shù)沐飘,表明了應(yīng)該用數(shù)據(jù)中的哪個(gè)字段進(jìn)行比較开仰,如果沒(méi)有聲明則默認(rèn)使用ID字段。

要注意的是薪铜,第二個(gè)參數(shù)必須是 ID 字段众弓、自定義的“外部 ID”字段或者索引字段。

假設(shè) Contact 對(duì)象中有一個(gè)“外部 ID”字段隔箍,名為“External_contact_person_number__c”谓娃,那么:

// 插入一條Contact數(shù)據(jù)
Contact con1 = new Contact(FirstName='A', LastName='LA');
insert con1;

// 插入數(shù)據(jù)之后更新數(shù)據(jù)
con1.Description = 'inserted contact 1';

// 新建另一條Contact數(shù)據(jù)
Contact con2 = new Contact(FirstName='B', LastName='LB');

// 將兩條Contact數(shù)據(jù)加入一個(gè)列表中
List<Contact> cons = new List<Contact> { con1, con2 };

// 對(duì)列表進(jìn)行upsert操作
upsert cons;

上面代碼執(zhí)行的結(jié)果是 con1 數(shù)據(jù)被更新了,con2 數(shù)據(jù)被插入了蜒滩。

如果上面的代碼改為:

Contact con1 = new Contact(FirstName='A', LastName='LA', External_contact_person_number__c = 'ex001');
insert con1;

Contact con2 = new Contact(FirstName='B', LastName='LB', External_contact_person_number__c = 'ex001');

upsert con2 Contact.Fields.External_contact_person_number__c;

那么系統(tǒng)在 upsert 時(shí)會(huì)比較 Contact 數(shù)據(jù)中的 External_contact_person_number__c 字段滨达,找到 External_contact_person_number__c 字段是 “ex001” 的數(shù)據(jù),然后直接進(jìn)行更新俯艰。所以上面代碼的執(zhí)行之后捡遍,系統(tǒng)中只有一條 Contact 記錄,其 FirstName 和 LastName 字段的值被更新為 “B”竹握。

注意画株,如果在 upsert 語(yǔ)句執(zhí)行時(shí),系統(tǒng)查找到系統(tǒng)中已經(jīng)有兩條或更多符合條件的記錄啦辐,則該操作會(huì)報(bào)錯(cuò)谓传,不會(huì)更新或插入任何數(shù)據(jù)。比如:

// 插入多條數(shù)據(jù)
List<Contact> conList = new List<Contact> {
    new Contact(FirstName='A', LastName='LA', External_contact_person_number__c = 'ex001'),
    new Contact(FirstName='B', LastName='LB', External_contact_person_number__c = 'ex001')
};
insert conList;

// 新建數(shù)據(jù)
Contact con = new Contact(FirstName='C', LastName='LC', External_contact_person_number__c = 'ex001');

// upsert新建的數(shù)據(jù)芹关,基于LastName字段
upsert con Contact.Fields.External_contact_person_number__c;

這段代碼會(huì)報(bào)錯(cuò)续挟,因?yàn)橄到y(tǒng)中已經(jīng)有了兩條 External_contact_person_number__c 為 “ex001” 的數(shù)據(jù),無(wú)法進(jìn)行插入或更新侥衬。

如果最后的 upsert 操作改為:

upsert con;

則不會(huì)有問(wèn)題双饥,因?yàn)楸容^的是 ID 字段,而 ID 字段必然是唯一的默穴,不存在于系統(tǒng)中,所以該記錄(con)會(huì)被插入博个。

Database 類

Apex中有Database類,其中包含了一組靜態(tài)函數(shù)际乘,它們的作用和 DML 語(yǔ)句類似:

  • Database.insert()
  • Database.update()
  • Database.upsert()
  • Database.delete()
  • Database.undelete()
  • Database.merge()
    與 DML 語(yǔ)句不同的是坡倔,每個(gè)函數(shù)都有一個(gè)可選布爾型參數(shù),可以決定當(dāng)操作的一組數(shù)據(jù)中部分?jǐn)?shù)據(jù)出現(xiàn)錯(cuò)誤時(shí)脖含,是否將沒(méi)有出錯(cuò)的數(shù)據(jù)繼續(xù)執(zhí)行相應(yīng)的命令罪塔。

比如:

Database.insert(accList, false);

如果插入的一組數(shù)據(jù) accList 中有不符合條件的數(shù)據(jù),那么系統(tǒng)會(huì)跳過(guò)這些數(shù)據(jù)养葵,將剩下的數(shù)據(jù)成功插入數(shù)據(jù)庫(kù)征堪,并且不會(huì)報(bào)錯(cuò)。

該布爾型參數(shù)默認(rèn)為“真”(true)关拒。當(dāng)有部分?jǐn)?shù)據(jù)出錯(cuò)時(shí)佃蚜,所有數(shù)據(jù)都不會(huì)被執(zhí)行相應(yīng)的操作,并報(bào)錯(cuò)着绊。

Database 類的操作返回值

Database 類的操作函數(shù)會(huì)返回一組值谐算,對(duì)于進(jìn)行操作的每一條數(shù)據(jù),都會(huì)有成功或失敗的信息归露。

// insert 的結(jié)果
Database.SaveResult[] = Database.insert(recordList, false);

// upsert 的結(jié)果
Database.UpsertResult[] = Database.upsert(recordList, false);

// delete 的結(jié)果
Database.DeleteResult[] = Database.delete(recordList, false);

SOQL

SOQL 是 Salesforce 提供的數(shù)據(jù)庫(kù)操作語(yǔ)言洲脂,全稱是 Salesforce Object Query Language,類似于 SQL剧包。

在 Developer Console 的 Query Editor 部分恐锦,可以鍵入 SOQL 語(yǔ)句并進(jìn)行查詢。

在 Apex 中疆液,可以直接調(diào)用 SOQL 語(yǔ)句操作一個(gè)或一組 sObject 對(duì)象一铅。

比如:

List<Account> accList = [SELECT Name FROM Account];

SOQL 語(yǔ)法

SOQL 基本語(yǔ)法和 SQL 類似,比如 SELECT 語(yǔ)句的格式是:

SELECT 字段 FROM sObject [WHERE 條件]

其中 WHERE 語(yǔ)句是可選部分堕油。

要注意的是:

  1. SELECT 后面聲明的字段需要用逗號(hào)隔開潘飘,并且不能用“*”來(lái)選取所有字段,必須聲明每個(gè)要查詢的字段
  2. 對(duì)于不存在于 SELECT 語(yǔ)句的字段馍迄,系統(tǒng)不會(huì)去查詢其值福也,所以后面的語(yǔ)句無(wú)法使用這些字段的值

比如:

List<Account> accList = [SELECT Id, Name FROM Account];

// 使用 Phone 字段會(huì)出錯(cuò)
// accList[0].Phone = '12345678';

查詢結(jié)果中的每個(gè) Account 對(duì)象只包含 Id 和 Name 字段的值,如果用戶想使用 Phone 字段的值攀圈,系統(tǒng)會(huì)報(bào)錯(cuò)。

SELECT 語(yǔ)句后面也可以加 ORDER BY 和 LIMIT 語(yǔ)句峦甩。比如:

List<Account> accList = [SELECT Id, Name FROM Account ORDER BY Name LIMIT 20];

通配符

在 SOQL 的 WHERE 語(yǔ)句中赘来,如果想查詢某字段包含某個(gè)值的話现喳,可以用通配符進(jìn)行模糊查詢。比如:

SELECT Id, Name FROM Account WHERE Name LIKE '%test%'

上面的語(yǔ)句查詢的是字段 Name 中包含 “test” 的所有 Account 記錄犬辰。

使用變量

如果要在 SOQL 查詢中使用變量嗦篱,則變量名前需要用“:”來(lái)引導(dǎo)。比如:

String queryStr = 'test';

List<Account> accList = [SELECT Id, Name FROM Account WHERE Name LIKE :queryStr];

關(guān)聯(lián)對(duì)象的查詢

在 SOQL 語(yǔ)句中幌缝,可以嵌套查詢相關(guān)聯(lián)的對(duì)象灸促。在子對(duì)象中,定義了和父對(duì)象相關(guān)聯(lián)的字段涵卵,其中的“子級(jí)關(guān)系名稱”屬性需要在查詢中使用浴栽。

對(duì)于標(biāo)準(zhǔn)對(duì)象,“子級(jí)關(guān)系名稱”可以直接使用轿偎。對(duì)于自定義對(duì)象典鸡,要在“子級(jí)關(guān)系名稱”后面加上“__r”。

比如:

// 嵌套查詢和 Account 相關(guān)的 Contact 對(duì)象坏晦,其中 “Contacts” 是 Contact 對(duì)象中和父對(duì)象 Account 關(guān)系字段的子級(jí)關(guān)系名稱
List<Account> accWithConList = [SELECT Name, 
                                        (SELECT FirstName, LastName FROM Contacts)
                                FROM Account
                                WHERE Name like '%test'
];

// 查詢到的 Contact 對(duì)象
List<Contact> firstConList = accWithConList[0].Contacts;

// 使用 Contact 對(duì)象中查詢到的值
String firstNameFromQuery = firstConList[0].FirstName;
String lastNameFromQuery = firstConList[0].LastName;

又如:

// 查詢父對(duì)象的字段內(nèi)容
List<Contact> conList = [SELECT Account.Name FROM Contact WHERE FirstName = 'testFirst'];

// 使用父對(duì)象的字段內(nèi)容
String accName = conList[0].Account.Name;

自定義對(duì)象的關(guān)聯(lián)對(duì)象

比如:

  1. 在系統(tǒng)中建立了 “Address__c” 對(duì)象和 “Street__c” 對(duì)象
  2. 每個(gè) “Address__c” 對(duì)象中包含若干個(gè) “Street__c” 對(duì)象
  3. 在 “Street__c” 對(duì)象中定義了字段表明和 “Address__c”的關(guān)系萝玷,其“子級(jí)關(guān)系名稱”的名字是 “Streets”。那么查詢可以這樣寫:
// 從父對(duì)象查詢子對(duì)象的字段
SELECT Name, (SELECT Name FROM Streets__r) FROM Address__c

// 從子對(duì)象查詢父對(duì)象的字段
SELECT Name, Address__r.Name FROM Street__c

SOSL

SOSL 是 Salesforce 提供的數(shù)據(jù)庫(kù)操作語(yǔ)言昆婿,全稱是 Salesforce Object Search Language球碉。

SOSL 主要用于在數(shù)據(jù)庫(kù)的各個(gè)對(duì)象中查詢符合條件的列。

SOSL 和 SOQL 類似仓蛆,都可以在 Apex 中直接調(diào)用睁冬。SOSL 返回的類型永遠(yuǎn)是一個(gè)包含了 sObject 對(duì)象列表的列表,即 List<List<SObject>> 類型多律。

比如痴突,對(duì)于所有 Account 和 Contact 對(duì)象,查詢?nèi)我蛔侄沃邪?“test” 的記錄:

List<List<SObject>> resultList = [FIND 'test' 
                                  IN ALL FIELDS 
                                  RETURNING Account(Name), Contact(FirstName, LastName)];

返回的結(jié)果便是符合條件的兩個(gè)列表狼荞,一個(gè)列表包含 Account 對(duì)象辽装,其中只有 Name 的值,另一個(gè)列表包含 Contact 對(duì)象相味,其中只有 FirstName 和 LastName 的值拾积。

SOSL語(yǔ)法

SOSL 的基本語(yǔ)法是:

FIND 要查詢的字符串 IN 要查找的字段 RETURNING 查詢結(jié)果包含的對(duì)象和字段名

其中:

  • 要查詢的字符串是無(wú)關(guān)大小寫的
  • 要查找的字段是可選參數(shù),默認(rèn)是所有字段丰涉,即 “ALL FIELDS”拓巧,也可以在此聲明只在某幾個(gè)字段中查詢,可以使用的僅限于:“NAME FIELDS”一死、“EMAIL FIELDS”肛度、“PHONE FIELDS”、“SIDEBAR FIELDS”
  • 查詢結(jié)果包含的對(duì)象和字段名可以包含一個(gè)或多個(gè)想要查詢的對(duì)象投慈,并聲明哪些字段保存在查詢結(jié)果中
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末承耿,一起剝皮案震驚了整個(gè)濱河市冠骄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌加袋,老刑警劉巖凛辣,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異职烧,居然都是意外死亡扁誓,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門蚀之,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蝗敢,“玉大人,你說(shuō)我怎么就攤上這事恬总∏捌眨” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵壹堰,是天一觀的道長(zhǎng)拭卿。 經(jīng)常有香客問(wèn)我,道長(zhǎng)贱纠,這世上最難降的妖魔是什么峻厚? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮谆焊,結(jié)果婚禮上惠桃,老公的妹妹穿的比我還像新娘。我一直安慰自己辖试,他們只是感情好辜王,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著罐孝,像睡著了一般呐馆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上莲兢,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天汹来,我揣著相機(jī)與錄音,去河邊找鬼改艇。 笑死收班,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谒兄。 我是一名探鬼主播摔桦,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼承疲!你這毒婦竟也來(lái)了酣溃?” 一聲冷哼從身側(cè)響起瘦穆,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤纪隙,失蹤者是張志新(化名)和其女友劉穎赊豌,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绵咱,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡碘饼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了悲伶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艾恼。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖麸锉,靈堂內(nèi)的尸體忽然破棺而出钠绍,到底是詐尸還是另有隱情,我是刑警寧澤花沉,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布柳爽,位于F島的核電站,受9級(jí)特大地震影響碱屁,放射性物質(zhì)發(fā)生泄漏磷脯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一娩脾、第九天 我趴在偏房一處隱蔽的房頂上張望赵誓。 院中可真熱鬧,春花似錦柿赊、人聲如沸俩功。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)诡蜓。三九已至,卻和暖如春奥邮,著一層夾襖步出監(jiān)牢的瞬間万牺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工洽腺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脚粟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓蘸朋,卻偏偏與公主長(zhǎng)得像核无,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子藕坯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容