JDBC

Apps Script は、標準の Java データベース接続テクノロジーのラッパーである JDBC サービスを介して外部データベースに接続できます。JDBC サービスは、Google Cloud SQL for MySQL、MySQL、Microsoft SQL Server、Oracle データベースをサポートしています。

JDBC を使用して外部データベースを更新するには、スクリプトでデータベースへの接続を開き、SQL ステートメントを送信して変更を行う必要があります。

Google Cloud SQL データベース

Google Cloud SQL を使用すると、Google のクラウド上に存在するリレーショナル データベースを作成できます。Cloud SQL では、使用量に応じて料金が発生する可能性があります。

Google Cloud SQL インスタンスは、Cloud SQL クイックスタートの手順に沿って作成できます。

Google Cloud SQL 接続の作成

Apps Script の JDBC サービスを使用して Google Cloud SQL データベースとの接続を確立するには、次の 2 つの方法があります。

これらのメソッドについて、以下で説明します。どちらも有効ですが、2 番目の方法では、データベースにアクセスするための一連の IP 範囲を承認する必要があります。

このメソッドは、Jdbc.getCloudSqlConnection(url) メソッドを使用して Google Cloud SQL MySQL インスタンスへの接続を作成します。データベースの URL は jdbc:google:mysql://subname の形式です。ここで、subnameGoogle Cloud コンソールの Cloud SQL インスタンスの [概要] ページに表示される MySQL のインスタンス接続名です。

Cloud SQL の SQL Server に接続するには、Jdbc.getConnection(url) をご覧ください。

Jdbc.getConnection(url) を使用する

この方法を使用するには、Apps Script のサーバーがデータベースに接続できるように、特定のクラスレス ドメイン間ルーティング(CIDR) IP アドレス範囲を承認する必要があります。スクリプトを実行する前に、次の手順を完了します。

  1. Google Cloud SQL インスタンスで、このデータソースから 1 つずつ IP 範囲を承認します。

  2. データベースに割り当てられた URL をコピーします。URL は jdbc:mysql:subname の形式になっているはずです。

これらの IP 範囲を承認すると、いずれかの Jdbc.getConnection(url) メソッドと上記でコピーした URL を使用して、Google Cloud SQL インスタンスへの接続を作成できます。

その他のデータベース

独自の MySQL、Microsoft SQL Server、または Oracle データベースがすでにある場合は、Apps Script の JDBC サービスを介して接続できます。

他のデータベース接続の作成

Apps Script の JDBC サービスを使用してデータベース接続を作成するには、データベース設定でこのデータソースの IP 範囲を承認する必要があります。

これらの許可リストを設定すると、いずれかの Jdbc.getConnection(url) メソッドとデータベースの URL を使用してデータベースへの接続を作成できます。

サンプルコード

次のサンプルコードでは、Google Cloud SQL データベースに接続することを前提としています。また、Jdbc.getCloudSqlConnection(url) メソッドを使用してデータベース接続を作成します。他のデータベースの場合は、Jdbc.getConnection(url) メソッドを使用してデータベース接続を作成する必要があります。

JDBC メソッドの詳細については、JDBC の Java ドキュメントをご覧ください。

データベース、ユーザー、テーブルを作成する

ほとんどのデベロッパーは、MySQL コマンドライン ツールを使用して、データベース、ユーザー、テーブルを作成します。ただし、以下に示すように、Apps Script でも同じことができます。スクリプトが必ずしも root としてデータベースに接続する必要がないように、他のユーザーを少なくとも 1 人作成することをおすすめします。

service/jdbc.gs
/**
 * Create a new database within a Cloud SQL instance.
 */
function createDatabase() {
  try {
    const conn = Jdbc.getCloudSqlConnection(instanceUrl, root, rootPwd);
    conn.createStatement().execute('CREATE DATABASE ' + db);
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log('Failed with an error %s', err.message);
  }
}

/**
 * Create a new user for your database with full privileges.
 */
function createUser() {
  try {
    const conn = Jdbc.getCloudSqlConnection(dbUrl, root, rootPwd);

    const stmt = conn.prepareStatement('CREATE USER ? IDENTIFIED BY ?');
    stmt.setString(1, user);
    stmt.setString(2, userPwd);
    stmt.execute();

    conn.createStatement().execute('GRANT ALL ON `%`.* TO ' + user);
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log('Failed with an error %s', err.message);
  }
}

/**
 * Create a new table in the database.
 */
function createTable() {
  try {
    const conn = Jdbc.getCloudSqlConnection(dbUrl, user, userPwd);
    conn.createStatement().execute('CREATE TABLE entries ' +
      '(guestName VARCHAR(255), content VARCHAR(255), ' +
      'entryID INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(entryID));');
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log('Failed with an error %s', err.message);
  }
}

データベースに書き込む

以下の例は、データベースに単一のレコードを書き込む方法と、500 件のレコードのバッチを書き込む方法を示しています。一括処理は、一括操作に不可欠です。

また、変数は ? で示されている、パラメータ化されたステートメントを使用している点にも注意してください。SQL インジェクション攻撃を防ぐには、パラメータ化されたステートメントを使用して、すべてのユーザー指定データをエスケープする必要があります。

service/jdbc.gs
/**
 * Write one row of data to a table.
 */
function writeOneRecord() {
  try {
    const conn = Jdbc.getCloudSqlConnection(dbUrl, user, userPwd);

    const stmt = conn.prepareStatement('INSERT INTO entries ' +
      '(guestName, content) values (?, ?)');
    stmt.setString(1, 'First Guest');
    stmt.setString(2, 'Hello, world');
    stmt.execute();
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log('Failed with an error %s', err.message);
  }
}

/**
 * Write 500 rows of data to a table in a single batch.
 */
function writeManyRecords() {
  try {
    const conn = Jdbc.getCloudSqlConnection(dbUrl, user, userPwd);
    conn.setAutoCommit(false);

    const start = new Date();
    const stmt = conn.prepareStatement('INSERT INTO entries ' +
      '(guestName, content) values (?, ?)');
    for (let i = 0; i < 500; i++) {
      stmt.setString(1, 'Name ' + i);
      stmt.setString(2, 'Hello, world ' + i);
      stmt.addBatch();
    }

    const batch = stmt.executeBatch();
    conn.commit();
    conn.close();

    const end = new Date();
    console.log('Time elapsed: %sms for %s rows.', end - start, batch.length);
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log('Failed with an error %s', err.message);
  }
}

データベースから読み取る

この例では、データベースから多数のレコードを読み取り、必要に応じて結果セットをループする方法を示します。

service/jdbc.gs
/**
 * Read up to 1000 rows of data from the table and log them.
 */
function readFromTable() {
  try {
    const conn = Jdbc.getCloudSqlConnection(dbUrl, user, userPwd);
    const start = new Date();
    const stmt = conn.createStatement();
    stmt.setMaxRows(1000);
    const results = stmt.executeQuery('SELECT * FROM entries');
    const numCols = results.getMetaData().getColumnCount();

    while (results.next()) {
      let rowString = '';
      for (let col = 0; col < numCols; col++) {
        rowString += results.getString(col + 1) + '\t';
      }
      console.log(rowString);
    }

    results.close();
    stmt.close();

    const end = new Date();
    console.log('Time elapsed: %sms', end - start);
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log('Failed with an error %s', err.message);
  }
}

接続を閉じる

スクリプトの実行が終了すると、JDBC 接続は自動的に終了します。(呼び出しを行った HTML サービスページが開いたままの場合でも、1 回の google.script.run 呼び出しは完全な実行としてカウントされます)。

スクリプトの終了前に接続、ステートメント、結果セットの処理が完了したことがわかっている場合は、JdbcConnection.close()JdbcStatement.close()、または JdbcResultSet.close() を呼び出して、それらを手動で閉じることをおすすめします。

アラートまたはプロンプトのダイアログを表示すると、開いている JDBC 接続も終了します。ただし、他の表示 UI 要素(カスタム メニュー、カスタム コンテンツを含むダイアログ、サイドバーなど)は表示できません。

Google、Google Workspace、および関連するマークとロゴは、Google LLC の商標です。その他すべての社名および製品名は、それぞれ該当する企業の商標です。