Schreiben von SOQL-Abfragen
Lernziele
Nachdem Sie diese Lektion abgeschlossen haben, sind Sie in der Lage, die folgenden Aufgaben auszuführen:
- Schreiben von SOQL in Apex
- Ausführen von SOQL-Abfragen mithilfe des Abfrage-Editors in der Entwicklerkonsole
- Ausführen von in Apex eingebetteten SOQL-Abfragen mithilfe von anonymem Apex-Code
- Abfragen verknüpfter Datensätze
Erste Schritte mit SOQL
Zum Auslesen eines Datensatzes aus Salesforce müssen Sie eine Abfrage schreiben. Salesforce bietet die Salesforce Object Query Language, kurz SOQL, mit der gespeicherte Datensätze ausgelesen werden können. SOQL ähnelt der Standardsprache SQL, ist jedoch auf die Lightning Platform zugeschnitten.
Da Apex direkten Zugriff auf in der Datenbank gespeicherte Salesforce-Datensätze hat, können Sie SOQL-Abfragen in Ihren Apex-Code einbetten und erhalten so auf direkte Weise Ergebnisse. Wenn SOQL in Apex eingebettet ist, wird es als Inline-SOQL bezeichnet.
Um SOQL-Abfragen in den Apex-Code einzufügen, setzen Sie die SOQL-Anweisung in eckige Klammern und weisen Sie den Rückgabewert einem Array von sObjects zu. Mit folgendem Beispiel etwa werden alle Accountdatensätze mit zwei Feldern, "Name" und "Phone", abgerufen und es wird ein Array von Account-sObjects zurückgegeben.
Account[] accts = [SELECT Name,Phone FROM Account];
Voraussetzungen
Einige Abfragen in diesem Abschnitt setzen voraus, dass die Organisation über Accounts und Kontakte verfügt. Bevor Sie die Abfragen ausführen, erstellen Sie einige Beispieldaten.
- Öffnen Sie in der Entwicklerkonsole über das Menü Debug das Fenster für die anonyme Ausführung.
- Fügen Sie den unten stehenden Codeauszug in das Fenster ein und klicken Sie auf Execute (Ausführen).
// Add account and related contact Account acct = new Account( Name='SFDC Computing', Phone='(415)555-1212', NumberOfEmployees=50, BillingCity='San Francisco'); insert acct; // Once the account is inserted, the sObject will be // populated with an ID. // Get this ID. ID acctID = acct.ID; // Add a contact to this account. Contact con = new Contact( FirstName='Carol', LastName='Ruiz', Phone='(415)555-1212', Department='Wingo', AccountId=acctID); insert con; // Add account with no contact 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;
Verwenden des Abfrage-Editors
Die Entwicklerkonsole umfasst die Abfrage-Editor-Konsole, mit der Sie SOQL-Abfragen ausführen und die Ergebnisse anzeigen können. Der Abfrage-Editor bietet eine schnelle Möglichkeit zum Überprüfen der Datenbank. Dies ist eine gute Methode, Ihre SOQL-Abfragen zu testen, bevor Sie sie zu Ihrem Apex-Code hinzufügen. Wenn Sie den Abfrage-Editor verwenden, müssen Sie nur die SOQL-Anweisung ohne den umgebenden Apex-Code angeben.
Führen Sie folgendes SOQL-Beispiel aus:
- Klicken Sie in der Developer Console auf die Registerkarte Query Editor (Abfrage-Editor).
- Kopieren Sie den folgenden Code, fügen Sie ihn in das erste Feld unter "Query Editor" ein und klicken Sie dann auf Execute (Ausführen).
SELECT Name,Phone FROM Account
Alle Accountdatensätze in Ihrer Organisation werden im Abschnitt "Query Results" (Abfrageergebnisse) als Zeilen mit Feldern angezeigt.
Grundlegende SOQL-Syntax
Die Syntax einer grundlegenden SOQL-Abfrage sieht wie folgt aus:
SELECT fields FROM ObjectName [WHERE Condition]
Die WHERE-Klausel ist optional. Beginnen wir mit einer sehr einfachen Abfrage. Die folgende Abfrage beispielsweise ruft Accounts sowie für jeden Account die Felder "Name" und "Telefon" ab:
SELECT Name,Phone FROM Account
Die Abfrage besteht aus zwei Teilen:
-
SELECT Name,Phone
: In diesem Teil werden die Felder aufgelistet, die abgerufen werden sollen. Die Felder werden nach dem Schlüsselwort SELECT in einer kommagetrennten Liste angegeben. Sie können auch nur ein Feld angeben, wobei kein Komma erforderlich ist (z. B.SELECT Phone
).
-
FROM Account
: In diesem Teil wird das Standardobjekt oder benutzerdefinierte Objekt angegeben, das abgerufen werden soll. In diesem Beispiel handelt es sich um "Account". Für ein benutzerdefiniertes Objekts namens "Invoice_Statement" wird "Invoice_Statement__c" angegeben.
Filtern von Abfrageergebnissen mit Bedingungen
Wenn in Ihrer Organisation mehr als ein Account vorhanden ist, werden alle zurückgegeben. Wenn nur solche Accounts zurückgegeben werden sollen, die eine bestimmte Bedingung erfüllen, können Sie diese Bedingung in die WHERE-Klausel einfügen. Mit dem folgenden Beispiel werden nur die Accounts abgerufen, deren Name "SFDC Computing" lautet. Beachten Sie, dass bei Vergleichen von Zeichenfolgen nicht zwischen Groß- und Kleinschreibung unterschieden wird.
SELECT Name,Phone FROM Account WHERE Name='SFDC Computing'
Die WHERE-Klausel kann mehrere Bedingungen enthalten, die mithilfe von logischen Operatoren (AND, OR) und Klammern gruppiert werden. Die folgende Abfrage beispielsweise gibt alle Accounts zurück, deren Name "SFDC Computing" lautet und die mehr als 25 Mitarbeiter haben:
SELECT Name,Phone FROM Account WHERE (Name='SFDC Computing' AND NumberOfEmployees>25)
Nachstehend folgt ein weiteres Beispiel mit einer komplexeren Bedingung. Diese Abfrage gibt alle diese Datensätze zurück:
- Alle SFDC Computing-Accounts
- Alle Accounts mit mehr als 25 Mitarbeitern und Los Angeles als Angabe für "Rechnungsanschrift Stadt"
SELECT Name,Phone FROM Account WHERE (Name='SFDC Computing' OR (NumberOfEmployees>25 AND BillingCity='Los Angeles'))
Anordnen von Abfrageergebnissen
Wenn eine Abfrage ausgeführt wird, gibt sie Datensätze aus Salesforce in willkürlicher Reihenfolge zurück, d. h., die Reihenfolge der Datensätze im zurückgegebenen Array ist nicht jedes Mal gleich, wenn die Abfrage ausgeführt wird. Sie können die zurückgegebene Datensatzgruppe jedoch sortieren, indem Sie eine ORDER BY-Klausel einfügen und das Feld angeben, nach dem die Datensatzgruppe sortiert werden soll. Mit folgendem Beispiel werden alle abgerufenen Accounts nach dem Namensfeld sortiert.
SELECT Name,Phone FROM Account ORDER BY Name
Die standardmäßige Sortierreihenfolge ist alphabetisch, angegeben als "ASC". Die vorherige Anweisung entspricht Folgendem:
SELECT Name,Phone FROM Account ORDER BY Name ASC
Um die Reihenfolge umzukehren, verwenden Sie das Schlüsselwort DESC für absteigende Reihenfolge:
SELECT Name,Phone FROM Account ORDER BY Name DESC
Sie können nach den meisten Felder sortieren, einschließlich numerischen Feldern und Textfeldern. Eine Sortierung nach Feldern wie Rich-Text-Feldern oder Auswahllisten mit Mehrfachauswahl ist nicht möglich.
Probieren Sie diese SOQL-Anweisungen im Abfrage-Editor aus und beobachten Sie, wie sich die Reihenfolge der zurückgegebenen Datensätze basierend auf dem Namensfeld ändert.
Begrenzen der Anzahl der zurückgegebenen Datensätze
Sie können die Anzahl der zurückgegebenen Datensätze auf eine beliebige Zahl begrenzen, indem Sie die Klausel "LIMIT n
" einfügen, wobei "n" für die Anzahl der Datensätze steht, die zurückgegeben werden soll. Das Begrenzen des Ergebnissatzes ist praktisch, wenn es keine Rolle für Sie spielt, welche Datensätze zurückgegeben werden, sondern Sie einfach nur mit einem Teil der Datensätze arbeiten möchten. Die folgende Abfrage beispielsweise ruft den ersten Account ab, der zurückgegeben wird. Beachten Sie, dass der zurückgegebene Wert bei Verwendung von "LIMIT 1
" ein Account und nicht ein Array ist.
Account oneAccountOnly = [SELECT Name,Phone FROM Account LIMIT 1];
Kombinieren aller Teile
Sie können die optionalen Klauseln in einer Abfrage kombinieren, und zwar in folgender Reihenfolge:
SELECT Name,Phone FROM Account WHERE (Name = 'SFDC Computing' AND NumberOfEmployees>25) ORDER BY Name LIMIT 10
Führen Sie die folgende SOQL-Abfrage in Apex im Fenster für die anonyme Ausführung in der Entwicklerkonsole aus. Untersuchen Sie anschließend die Debug-Anweisungen im Debug-Protokoll. Es sollte ein Beispielaccount zurückgegeben werden.
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.'); // Write all account array info System.debug(accts);
Zugreifen auf Variablen in SOQL-Abfragen
SOQL-Anweisungen in Apex können Apex-Code-Variablen und -Ausdrücke referenzieren, wenn ihnen ein Doppelpunkt (:) vorangestellt ist. Die Verwendung einer lokalen Variablen in einer SOQL-Anweisung wird als Bindung bezeichnet.
Das folgende Beispiel zeigt, wie die Variable "targetDepartment
" in der WHERE-Klausel verwendet wird.
String targetDepartment = 'Wingo'; Contact[] techContacts = [SELECT FirstName,LastName FROM Contact WHERE Department=:targetDepartment];
Abfragen zugehöriger Datensätze
Datensätze in Salesforce können über Beziehungen miteinander verknüpft werden: Nachschlagebeziehungen oder Master-Detail-Beziehungen. Der Kontakt beispielsweise weist eine Nachschlagebeziehung mit einem Account auf. Wenn Sie einen Kontakt erstellen oder aktualisieren, können Sie ihn einem Account zuordnen. Die Kontakte, die demselben Account zugeordnet sind, werden in einer Themenliste auf der Seite des Accounts angezeigt. Auf die gleiche Weise, wie Sie verknüpfte Datensätze auf der Salesforce-Benutzeroberfläche anzeigen können, können Sie verknüpfte Datensätze in SOQL abfragen.
Um mit einem übergeordneten Datensatz verknüpfte untergeordnete Datensätze abzurufen, fügen Sie für die untergeordneten Datensätze eine innere Abfrage hinzu. Die FROM-Klausel der inneren Abfrage wird für den Beziehungsnamen und nicht für einen Salesforce-Objektnamen ausgeführt. Das folgende Beispiel enthält eine innere Abfrage zum Abrufen aller Kontakte, die jedem zurückgegebenen Account zugeordnet sind. Die FROM-Klausel gibt als Beziehung "Contacts" an, die eine Standardbeziehung in Accounts ist und Accounts und Kontakte miteinander verknüpft.
SELECT Name, (SELECT LastName FROM Contacts) FROM Account WHERE Name = 'SFDC Computing'
Im nächsten Beispiel ist die SOQL-Beispielabfrage in Apex eingebettet und es wird gezeigt, wie die untergeordneten Datensätze aus dem SOQL-Ergebnis abgerufen werden, indem im sObject der Beziehungsname "Contacts" verwendet wird.
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);
Mithilfe der Dot-Notation können Sie eine Beziehung von einem untergeordneten Objekt (Kontakt) zu einem Feld im übergeordneten Objekt (Account.Name) durchlaufen. Der folgende Apex-Codeauszug beispielsweise fragt Kontaktdatensätze mit dem Vornamen "Carol" ab und kann den Namen von Carols zugeordnetem Account abrufen, indem er die Beziehung zwischen Accounts und Kontakten durchläuft.
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);
Abfragen von Datensätzen in Batches mithilfe von For-Schleifen in SOQL
Mit einer SOQL-For-Schleife können Sie eine SOQL-Abfrage in eine For
-Schleife einfügen. Die Ergebnisse einer SOQL-Abfrage können in der Schleife durchlaufen werden. SOQL-For-Schleifen verwenden eine andere Methode zum Abrufen von Datensätzen. Datensätze werden mittels effizienter Blockerstellung mit Aufrufen an die Methoden "query" und "queryMore" der SOAP-API abgerufen. Durch Verwendung von SOQL-For-Schleifen können Sie vermeiden, die maximal zulässige Heap-Größe zu überschreiten.
SOQL-For
-Schleifen durchlaufen alle von einer SOQL-Abfrage zurückgegebenen sObject-Datensätze. Die Syntax einer SOQL-For
-Schleife lautet entweder:
for (variable : [soql_query]) { code_block }
oder
for (variable_list : [soql_query]) { code_block }
Sowohl variable
als auch variable_list
müssen denselben Typ aufweisen wie die sObjects, die von der soql_query
zurückgegeben werden.
Vorzugsweise sollte das sObject-Listenformat der SOQL-For-Schleife verwendet werden, da die Schleife für jedes Batch von 200 sObjects einmal ausgeführt wird. Auf diese Weise können Sie Batches von Datensätzen bearbeiten und DML-Vorgänge in einem Batch ausführen und so das Erreichen von Obergrenzen vermeiden.
insert new Account[]{new Account(Name = 'for loop 1'), new Account(Name = 'for loop 2'), new Account(Name = 'for loop 3')}; // The sObject list format executes the for loop once per returned batch // of records Integer i=0; Integer j=0; for (Account[] tmp : [SELECT Id FROM Account WHERE Name LIKE 'for loop _']) { j = tmp.size(); i++; } System.assertEquals(3, j); // The list should have contained the three accounts // named 'yyy' System.assertEquals(1, i); // Since a single batch can hold up to 200 records and, // only three records should have been returned, the // loop should have executed only once
Ressourcen