intra-mart Accel Platform スクリプト開発モデル プログラミングガイド 第17版 2021-12-01

データベース

データベースの種類

intra-mart Accel Platform では以下の3種類のデータベースを利用します。
  • システムデータベース

    システムのデータを保存するデータベースです。
    システムデータべースはシステム内部で利用されるため、使用しないでください。
  • テナントデータベース

    テナント内で利用するデータを保存するデータベースです。
  • シェアードデータベース

    intra-mart Accel Platform システム外のデータを保存するデータベースです。
    外部システムと連携したい場合等に利用してください。

プログラミング方法

トランザクション

ここではトランザクション処理の実装方法を解説します。
トランザクションはTransactionオブジェクトのbeginメソッドに実行関数を渡すことで、処理終了時に自動的にコミットされます。
// トランザクション処理
Transaction.begin(function() {
    // クエリ実行
    var result = new TenantDatabase().execute(sql, param);
    if(result.error) {
        // エラー時はロールバックします。
        Transaction.rollback();
    }
});
上記のように実行関数を渡すことで、処理が正常に終了した場合はコミット処理、例外が発生した場合はロールバック処理が自動的に実行される為、トランザクションのコミット/ロールバックの実行漏れを防ぐことができます。

クエリの実行

クエリの実行方法は、接続先データベースによって異なります。
  • テナントデータベース

    // テナントデータベースへクエリを実行します。
    var database = new TenantDatabase();
    var result = database.execute("select * from b_m_account_b");
    
  • シェアードデータベース

    // 接続ID「sample」で設定されているシェアードデータベースへクエリを実行します。
    var database = new SharedDatabase("sample");
    var result = database.execute("select * from b_m_account_b");
    
prepared statementを利用する場合はDbParameterオブジェクトを使用します。
// prepared statementを使用してクエリを実行します。
var sql = "select * from b_m_account_b where user_cd = ? and login_failure_count = ?";
var result = new TenantDatabase().execute(sql, [
    DbParameter.string("aoyagi"),
    DbParameter.number(0)
]);

外だしSQLの利用

外だしSQLは、SQLをプログラムの外に出して、そのSQLをプログラムから実行する機能です。
外だしSQLを利用する場合は、「.sql」という拡張子のテキストファイルにSQLを記述し、「%CONTEXT_PATH%/WEB-INF/jssp/src」配下の任意のディレクトリに置いてください。
SQLファイル「%CONTEXT_PATH%/WEB-INF/jssp/src/sample/sql/get_sample_data.sql」を使用する場合は以下のように実装します。
// 外だしSQLを利用してクエリを実行します。
var database = new TenantDatabase();
var result = database.executeByTemplate('sample/sql/get_sample_data', params);

読み込まれるファイル

外だしSQLは接続先データベースのデータベース種別ごとに利用するSQLファイルをわけることができます。
データベース種別ごとにSQLファイルをわける場合は、ファイル名のサフィックスのデータベース種別を付けます。
  • 例:データべ-ス種別がOracleでSQLファイル名が「get_sample_data.sql」の場合
    • SQLファイル名を「get_sample_data_oracle.sql」とします。
上記のように、サフィックスをつけたSQLファイルを用意することで、データベース種別がOracleの場合、「get_sample_data_oracle.sql」が利用され、それ以外のデータベースの場合「get_sample_data.sql」が利用されます。
SQLファイルにつける各データベースのサフィックスは以下のとおりです。
データベース サフィックス
Oracle _oracle
SQLServer _sqlserver
PostgreSQL _postgre

SQLファイルの記述例

  • 例1 2Way-SQLの利用

    2Way-SQLは、コメントでプログラムとのマッピングを書くことで、SQL*PlusなどのSQLのツールでもそのまま実行が可能となっているSQL文です。
    • SQLファイル「sample.sql」
    SELECT *
    FROM b_m_account_b
    WHERE user_cd = /*userCd*/'aoyagi'
    
    • プログラム「sample.js」
    new TenantDatabase().executeByTemplate('sample', {
        userCd : DbParameter.string("harada")
    });
    
    プログラムを実行するとuser_cd=’harada’のデータを取得します。
    「sample.sql」をツール等でそのまま実行するとuser_cd=’aoyagi’のデータを取得します。
    プログラム実行時は、WHERE句のコメント部分をprepared statementに置き換えて実行します。
    SQLファイルのコメント部分(/パラメータ名/)に「:データ型」をつけるとDbParameterを使用せずに
    prepared statementを利用できます。
    • SQLファイル「sample.sql」
    SELECT *
    FROM b_m_account_b
    WHERE user_cd = /*userCd:string*/'aoyagi'
    
    • プログラム「sample.js」
    new TenantDatabase().executeByTemplate('sample', {
        userCd : "harada"
    });
    
  • 例2 prepared statementの利用

    prepared statement (?を含むSQL) をSQLファイルに記述した場合、その出現順にプロパティ名を
    $1, $2, …, $Nとしたオブジェクトを引数に指定します。
    • SQLファイル「sample.sql」
    SELECT *
    FROM b_m_account_b
    WHERE user_cd = ? AND login_failure_count = ?
    
    • プログラム「sample.js」
    new TenantDatabase().executeByTemplate('sample', {
        $1 : DbParameter.string('aoyagi'),
        $2 : DbParameter.number(0)
    });
    
  • 例3 文字列の置換

    SQLファイルに記述されたクエリ文字列を動的に置換してSQLを実行したい場合はコメント内に
    “$”をつけてパラメータ名を指定します。
    • SQLファイル「sample.sql」
    SELECT *
    FROM b_m_account_b
    ORDER BY /*$order*/'user_cd'
    
    • プログラム「sample.js」
    new TenantDatabase().executeByTemplate('sample', {
        order : "user_cd"
    });
    
    ORDER BY句のようにprepared statementを利用できない部分の文字列を置換したい場合等に利用します。
  • 例4 条件分岐

    特定の条件によって実行するSQLを動的に変更したい場合は/IF/ /END/を利用します。
    • SQLファイル「sample.sql」
    SELECT *
    FROM b_m_account_b
    WHERE
        /*IF userCd != null*/
        user_cd LIKE /*userCd:string*/'aoyagi'
        /*END*/
        /*IF predicate()*/
        AND login_failure_count = /*failureCount:number*/0
        /*END*/
    
    • プログラム「sample.js」
    new TenantDatabase().executeByTemplate('sample', {
        userCd : "harada",
        failureCount : 0,
        predicate : function() {
            return true;
        }
    });
    
    条件分岐によってWHERE句が空白になる等、不正なSQLが実行される可能性がある場合は、WHERE句を/BEGIN/ /END/で囲みます。
    /BEGIN/ /END/を使うことで、以下の処理が行われ、不正なSQLが実行されるのを防ぐことができます。
    1. すべての条件が不成立の場合、WHEREそのものをSQLから削除します。
    2. はじめに成立した条件のクエリ文字列がANDで始まっている場合、ANDを削除します。
    • SQLファイル「sample.sql」
    SELECT *
    FROM b_m_account_b
    /*BEGIN*/
    WHERE
        /*IF userCd != null*/
        user_cd LIKE /*userCd:string*/'aoyagi'
        /*END*/
        /*IF predicate()*/
        AND login_failure_count = /*failureCount:number*/0
        /*END*/
    /*END*/