[PHP]DB2のdb2_free_stmtでステートメントを解放!リソース管理の基本

PHP

こんにちは!今回は、DB2データベースのdb2_free_stmt関数について、実践的に解説します。この関数は、プリペアドステートメントのリソースを解放するために使用します。

db2_free_stmtとは?🔄

プリペアドステートメントに関連付けられたリソースを解放する関数です。メモリリークを防ぎ、効率的なリソース管理を実現します。

基本的な使い方

bool db2_free_stmt ( resource $stmt )

基本的な使用例

例1:シンプルな使用方法

$sql = "SELECT * FROM employees WHERE dept_id = ?";
$stmt = db2_prepare($connection, $sql);

db2_bind_param($stmt, 1, $dept_id, DB2_PARAM_IN);
db2_execute($stmt);

// データ処理後、ステートメントを解放
db2_free_stmt($stmt);

実践的な使用例

例1:プリペアドステートメントの再利用

function processEmployees($connection, $departments) {
    $sql = "SELECT * FROM employees WHERE department = ?";
    $stmt = db2_prepare($connection, $sql);

    try {
        foreach ($departments as $dept) {
            db2_bind_param($stmt, 1, $dept, DB2_PARAM_IN);
            db2_execute($stmt);

            while ($row = db2_fetch_assoc($stmt)) {
                processEmployee($row);
            }
        }
    } finally {
        // ステートメントを必ず解放
        db2_free_stmt($stmt);
    }
}

例2:複数のステートメント管理

class StatementManager {
    private $statements = [];

    public function prepare($connection, $sql) {
        $stmt = db2_prepare($connection, $sql);
        $this->statements[] = $stmt;
        return $stmt;
    }

    public function freeAll() {
        foreach ($this->statements as $stmt) {
            if ($stmt) {
                db2_free_stmt($stmt);
            }
        }
        $this->statements = [];
    }

    public function __destruct() {
        $this->freeAll();
    }
}

例3:トランザクション処理

function executeTransaction($connection) {
    $stmts = [];

    try {
        db2_autocommit($connection, DB2_AUTOCOMMIT_OFF);

        // 複数のステートメントを準備
        $stmts[] = db2_prepare($connection, "INSERT INTO table1 VALUES (?)");
        $stmts[] = db2_prepare($connection, "UPDATE table2 SET col = ? WHERE id = ?");

        // 処理実行
        db2_bind_param($stmts[0], 1, $value1, DB2_PARAM_IN);
        db2_execute($stmts[0]);

        db2_bind_param($stmts[1], 1, $value2, DB2_PARAM_IN);
        db2_bind_param($stmts[1], 2, $id, DB2_PARAM_IN);
        db2_execute($stmts[1]);

        db2_commit($connection);

    } catch (Exception $e) {
        db2_rollback($connection);
        throw $e;

    } finally {
        // すべてのステートメントを解放
        foreach ($stmts as $stmt) {
            if ($stmt) {
                db2_free_stmt($stmt);
            }
        }
    }
}

エラーハンドリングとリソース管理

1. 安全なステートメント解放

function safelyFreeStatement($stmt) {
    try {
        if ($stmt && is_resource($stmt)) {
            return db2_free_stmt($stmt);
        }
    } catch (Exception $e) {
        error_log("ステートメント解放エラー: " . $e->getMessage());
    }
    return false;
}

2. 複数ステートメントの管理

class PreparedStatements {
    private $statements = [];

    public function add($stmt) {
        $this->statements[] = $stmt;
    }

    public function freeAll() {
        foreach ($this->statements as $key => $stmt) {
            if (safelyFreeStatement($stmt)) {
                unset($this->statements[$key]);
            }
        }
    }
}

メモリ管理のベストプラクティス 🔧

1. 即時解放パターン

function quickPreparedQuery($connection, $sql, $params) {
    $stmt = db2_prepare($connection, $sql);

    try {
        foreach ($params as $index => $param) {
            db2_bind_param($stmt, $index + 1, $param, DB2_PARAM_IN);
        }

        $result = db2_execute($stmt);
        return $result;

    } finally {
        db2_free_stmt($stmt);
    }
}

2. ステートメントプール

class StatementPool {
    private static $pool = [];

    public static function get($connection, $sql) {
        $key = md5($sql);
        if (!isset(self::$pool[$key])) {
            self::$pool[$key] = db2_prepare($connection, $sql);
        }
        return self::$pool[$key];
    }

    public static function freeAll() {
        foreach (self::$pool as $stmt) {
            db2_free_stmt($stmt);
        }
        self::$pool = [];
    }
}

Tips & 注意点 💡

1. リソースリーク防止

function preventResourceLeak($connection, $sql) {
    $stmt = null;
    try {
        $stmt = db2_prepare($connection, $sql);
        // 処理
    } finally {
        if ($stmt) {
            db2_free_stmt($stmt);
        }
    }
}

2. 条件付きステートメント解放

function conditionalFree($stmt, $condition) {
    if ($condition && $stmt) {
        return db2_free_stmt($stmt);
    }
    return false;
}

まとめ

  • db2_free_stmtはプリペアドステートメントのリソース解放に重要
  • try-finallyブロックでの確実な解放を心がける
  • 複数のステートメントを適切に管理する
  • メモリリークを防ぐために必ず使用する

適切なリソース管理でアプリケーションのパフォーマンスを維持しましょう!

Happy Coding! 😊

タイトルとURLをコピーしました