2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SalesforceのApex入門:データ操作からバルク処理まで

Posted at

はじめに

Salesforceの開発を始めたばかりの方にとって、Apexコンソールは非常に便利なツールです。このツールを使うことで、簡単なデータ操作からデバッグまでをブラウザ上で実行できます。この記事では、Apexコンソールの基本的な使い方から、実践的なデータ操作手法までを解説します。

image.png

目次

  1. System.debug()の使い方
  2. SOQL基礎からデータ取得
  3. コンソールでのデバッグログの見方
  4. よくあるエラーと対処法
  5. バルク処理とガバナンス制限
  6. 安全なデータ操作の実践

1. System.debug()の使い方

image.png

基本的な使い方

System.debug()は、Apexでのデバッグ出力の基本となるメソッドです。

// 基本的な出力
System.debug('Hello World');

// 変数の値を出力
String name = 'Salesforce';
System.debug('name: ' + name);

// オブジェクトの値を出力
Account acc = new Account(Name='Test Account');
System.debug('Account: ' + acc);

デバッグレベルの指定

System.debug()には、ログレベルを指定することができます。

// ログレベルの指定
System.debug(LoggingLevel.ERROR, 'エラーレベルのメッセージ');
System.debug(LoggingLevel.WARN, '警告レベルのメッセージ');
System.debug(LoggingLevel.INFO, '情報レベルのメッセージ');

2. SOQL基礎からデータ取得

image.png

基本的なクエリ

SOQLを使用して、Salesforceのデータを取得する方法を見ていきましょう。

// 単純なクエリ
List<Account> accounts = [SELECT Id, Name FROM Account LIMIT 10];
System.debug('Accounts: ' + accounts);

// WHERE句を使用したフィルタリング
List<Contact> contacts = [
    SELECT Id, FirstName, LastName, Email 
    FROM Contact 
    WHERE Email != null 
    LIMIT 5
];
System.debug('Contacts with email: ' + contacts);

// 関連オブジェクトの取得
List<Account> accountsWithContacts = [
    SELECT Id, Name, (SELECT FirstName, LastName FROM Contacts)
    FROM Account
    WHERE Id IN (SELECT AccountId FROM Contact)
    LIMIT 5
];
System.debug('Accounts with contacts: ' + accountsWithContacts);

データ操作の実践例

// データの挿入
Account newAccount = new Account(Name='Test Account');
insert newAccount;
System.debug('Inserted Account: ' + newAccount);

// データの更新
newAccount.Name = 'Updated Account';
update newAccount;
System.debug('Updated Account: ' + newAccount);

// データの削除
delete newAccount;
System.debug('Account deleted');

3. コンソールでのデバッグログの見方

image.png

デバッグログの設定方法

  1. 設定から「デバッグログ」を開く
  2. 「新規」をクリックして新しいトレースフラグを作成
  3. 対象のユーザを選択
  4. デバッグレベルを設定(初めは「FINEST」がおすすめ)

ログの重要な項目

  • EXECUTION_STARTED:実行開始
  • USER_DEBUG:System.debug()の出力
  • SOQL_EXECUTE_BEGIN:SOQLクエリの実行開始
  • DML_BEGIN:DML操作の開始
  • EXCEPTION_THROWN:例外発生

ログの読み方の例

43.0 (29810000)|USER_DEBUG|[2]|DEBUG|Hello World
43.0 (29960000)|SOQL_EXECUTE_BEGIN|[5]|SELECT Id, Name FROM Account LIMIT 1
43.0 (30960000)|SOQL_EXECUTE_END|[5]
43.0 (31010000)|USER_DEBUG|[6]|DEBUG|Account: Account:{Id=001xx000003Gyl2AAC, Name=Test Account}

4. よくあるエラーと対処法

image.png

DMLエラー

try {
    // 必須項目が未入力の場合
    Account invalidAccount = new Account();
    insert invalidAccount;
} catch (DmlException e) {
    System.debug('エラー: ' + e.getMessage());
    // エラーメッセージ: 必須項目(名前)が入力されていません。
}

DML(Data Manipulation Language)は、Salesforceのデータベースを操作するための言語や操作のことを指します。

SOQLエラー

try {
    // 存在しないフィールドを参照
    List<Account> accounts = [SELECT InvalidField FROM Account];
} catch (QueryException e) {
    System.debug('エラー: ' + e.getMessage());
    // エラーメッセージ: No such column 'InvalidField' on entity 'Account'
}

リミットエラーの防止

// クエリの件数制限チェック
if (Limits.getQueries() < Limits.getLimitQueries()) {
    List<Account> accounts = [SELECT Id FROM Account LIMIT 1];
}

// DML操作の制限チェック
if (Limits.getDmlStatements() < Limits.getLimitDmlStatements()) {
    Account acc = new Account(Name='Test');
    insert acc;
}

5. バルク処理とガバナンス制限

image.png

Salesforceのガバナンス制限を理解する

Salesforceには様々な制限があり、これらを意識したコーディングが重要です:

// 主な制限値の確認方法
System.debug('SOQLクエリ制限: ' + Limits.getLimitQueries() + '/' + Limits.getQueries());
System.debug('DML制限: ' + Limits.getLimitDmlStatements() + '/' + Limits.getDmlStatements());
System.debug('ヒープサイズ制限: ' + Limits.getLimitHeapSize() + '/' + Limits.getHeapSize());

バルク処理の実装例

// 悪い例:ループ内でのDML
for (Account acc : accounts) {
    update acc; // ガバナンス制限に早く到達してしまう
}

// 良い例:リストでまとめて処理
List<Account> accountsToUpdate = new List<Account>();
for (Account acc : accounts) {
    acc.Description = 'Updated';
    accountsToUpdate.add(acc);
}
update accountsToUpdate; // 1回のDMLで処理

// Database.insertの使用例(部分的な成功を許容)
Database.SaveResult[] results = Database.insert(accountsToUpdate, false);
for (Database.SaveResult sr : results) {
    if (!sr.isSuccess()) {
        System.debug('Error: ' + sr.getErrors()[0].getMessage());
    }
}

トリガーでのバルク処理のベストプラクティス

// トリガーでの効率的なデータ処理例
public class AccountTriggerHandler {
    public static void handleBeforeInsert(List<Account> newAccounts) {
        // 関連データを1回のクエリで取得
        Set<String> accountNames = new Set<String>();
        for (Account acc : newAccounts) {
            accountNames.add(acc.Name);
        }
        
        // 重複チェックの例
        Map<String, Account> existingAccounts = new Map<String, Account>();
        for (Account acc : [SELECT Name FROM Account WHERE Name IN :accountNames]) {
            existingAccounts.put(acc.Name, acc);
        }
        
        // バルク処理での検証
        for (Account acc : newAccounts) {
            if (existingAccounts.containsKey(acc.Name)) {
                acc.Name.addError('同じ名前のアカウントが既に存在します');
            }
        }
    }
}

6. 安全なデータ操作の実践

image.png

テスト環境と本番環境の違い

@isTest
private class AccountOperationsTest {
    @isTest static void testAccountInsert() {
        // テストデータの作成
        Account testAcc = new Account(Name = 'Test Account');
        
        Test.startTest();
        insert testAcc;
        Test.stopTest();
        
        // 検証
        Account insertedAcc = [SELECT Id, Name FROM Account WHERE Id = :testAcc.Id];
        System.assertEquals('Test Account', insertedAcc.Name);
    }
}

データ操作の安全性を高める

// トランザクション制御
Savepoint sp = Database.setSavepoint();
try {
    Account acc = new Account(Name = 'Test');
    insert acc;
    Contact con = new Contact(); // 意図的にエラーを発生
    insert con;
} catch (Exception e) {
    Database.rollback(sp);
    System.debug('エラーが発生したため、ロールバックしました: ' + e.getMessage());
}

// エラーハンドリングの改善例
public class CustomException extends Exception {}

public void createAccount(String accountName) {
    if (String.isBlank(accountName)) {
        throw new CustomException('アカウント名は必須です');
    }
    
    try {
        insert new Account(Name = accountName);
    } catch (DmlException e) {
        throw new CustomException('アカウントの作成に失敗しました: ' + e.getMessage());
    }
}

デバッグログの詳細な解析例

エラーシナリオの再現と解析

// DMLエラーの例
43.0 (29810000)|EXCEPTION_THROWN|[5]|System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Name]: [Name]

// ガバナンス制限エラーの例
43.0 (29810000)|EXCEPTION_THROWN|[10]|System.LimitException: Too many SOQL queries: 101

// 実行時エラーの例
43.0 (29810000)|EXCEPTION_THROWN|[15]|System.NullPointerException: Attempt to de-reference a null object

ログの解析ポイント

  1. タイムスタンプ: 43.0 (29810000)
  2. イベントタイプ: EXCEPTION_THROWN, USER_DEBUG など
  3. 行番号: [5], [10], [15]
  4. エラーの種類と詳細情報

デバッグログの設定最適化

// デバッグレベルの詳細設定例
LoggingLevel debugLevel = LoggingLevel.FINEST;
System.debug(debugLevel, '詳細なデバッグ情報');

// パフォーマンス分析用のログ
System.debug(LoggingLevel.INFO, 'Process Start: ' + DateTime.now());
// 処理
System.debug(LoggingLevel.INFO, 'Process End: ' + DateTime.now());

まとめ

image.png

Apexコンソールは、Salesforceの開発において非常に強力なツールです。System.debug()を使ったデバッグ、SOQLによるデータ取得、デバッグログの確認、そしてエラー処理の基本を理解することで、より効率的な開発が可能になります。

参考リンク

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?