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

Schreiben von SOQL-Abfragen

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.

  1. Öffnen Sie in der Entwicklerkonsole über das Menü Debug das Fenster für die anonyme Ausführung.
  2. 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:

  1. Klicken Sie in der Entwicklerkonsole auf die Registerkarte Query Editor (Abfrage-Editor).
  2. 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:

  1. 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").
  2. 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.

Über die Grundlagen hinaus

Im Gegensatz zu anderen SQL-Sprachen können Sie nicht "*" als Platzhalter für alle Felder angeben. Sie müssen jedes abzurufende Feld explizit angeben. Wenn Sie versuchen, auf ein Feld zuzugreifen, das Sie in der SELECT-Klausel nicht angegeben haben, wird ein Fehler ausgegeben, da das Feld nicht abgerufen wurde.

Sie müssen das ID-Feld in der Abfrage nicht angeben, das es in Apex-Abfragen stets zurückgegeben wird, unabhängig davon, ob es in der Abfrage angegeben ist. Beispiel: "SELECT Id,Phone FROM Account" und "SELECT Phone FROM Account" sind synonyme Anweisungen. Das ID-Feld sollte jedoch angegeben werden, wenn es das einzige Feld ist, das Sie abrufen, da mindestens ein Feld aufgelistet werden muss: "SELECT Id FROM Account". Es empfiehlt sich auch, das ID-Feld beim Ausführen einer Abfrage im Abfrage-Editor anzugeben, da das ID-Feld nur angezeigt wird, wenn es angegeben ist.

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 "SFDC Computing"-Accounts oder alle Accounts mit mehr als 25 Mitarbeitern zurück, deren Stadt in der Rechnungsanschrift Los Angeles lautet.

SELECT Name,Phone FROM Account WHERE (Name='SFDC Computing' OR (NumberOfEmployees>25 AND BillingCity='Los Angeles'))

Über die Grundlagen hinaus

Statt für den Vergleich den Gleichheitsoperator (=) zu verwenden, können Sie mit dem Operator LIKE Fuzzy-Abgleiche vornehmen. Mit folgender Bedingung können Sie beispielsweise alle Accounts abrufen, deren Name mit "SFDC" beginnt: WHERE Name LIKE 'SFDC%'. Das Platzhalterzeichen "%" gleicht beliebige Zeichen oder kein Zeichen ab. Das Zeichen "_" hingegen kann zum Abgleichen von nur einem Zeichen verwendet werden.

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 verknüpfter 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);
Hinweis

Hinweis

Die Beispiele in diesem Abschnitt basieren auf Standardobjekten. Benutzerdefinierte Objekte können ebenfalls mithilfe benutzerdefinierter Beziehungen miteinander verknüpft werden. Die Namen benutzerdefinierter Beziehungen enden mit dem Suffix "__r". Um beispielsweise Rechnungsaufstellungen mit Belegposten zu verknüpfen, verwenden Sie die Beziehung "Line_Items__r" im benutzerdefinierten Objekt "Invoice_Statement__c".

Abfragen von Datensätzen in Batches mithilfe von SOQL-For-Schleifen

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
Lernen Sie weiter kostenlos!
Registrieren Sie sich für einen Account, um fortzufahren.
Was ist für Sie drin?
  • Holen Sie sich personalisierte Empfehlungen für Ihre Karriereplanung
  • Erproben Sie Ihre Fähigkeiten mithilfe praktischer Aufgaben und Quizze
  • Verfolgen Sie Ihre Fortschritte nach und teilen Sie sie mit Arbeitgebern
  • Nutzen Sie Mentoren und Karrierechancen