GoogleAppsScript
gas
FusionTables
株式会社Smew

【GoogleAppsScript】FusionTablesへのUPDATE文の書き方

More than 1 year has passed since last update.

素直に書くとエラーになる

Id Text
1 Str1
2 Str2
3 Str3
4 Str4
5 Str5
6 Str6
7 Str7
8 Str8
9 Str9
10 Str10

例として、FusionTabels上にこのようなデータがあって
Id = 5 の Text を書き換えたい場合、

updateTable.gs
function updateTable(){
  var query;
  var tableId = "1_C...lpL";  // docid

  // 変更するテキスト
  var str = "Changed Str";

  query = "UPDATE " + tableId + " SET Text = '" + str + "' WHERE Id = 5"

  FusionTables.Query.sql(query);
}

このように書きたくなりますが、

Invalid query: Parse error near 'Id' (line 1, position 73). Expecting ROWID instead.

WHERE句で上記エラーが出てしまいます、
エラーメッセージを見る限り、「"ROWID"を使いましょう」ということらしい。

ROWIDとは

ブラウザ上では確認できませんが、
どうやらROWIDフィールドが存在しているようです。

ROWID Id Text
1 1 Str1
2 2 Str2
3 3 Str3
10 10 Str10
var select = "SELECT ROWID, Id, Text FROM " + tableId + " ORDER BY Id";
var result = FusionTables.Query.sqlGet(select);
Logger.log(result);

上記を投げると、

{
    kind=fusiontables#sqlresponse,
    columns=[rowid, Id, Text],
    rows=[
        [1, 1, Str1],
        [2, 2, Str2],
        [3, 3, Str3],
        [4, 4, Str4],
        [5, 5, Str5],
        [6, 6, Str6],
        [7, 7, Str7],
        [8, 8, Str8],
        [9, 9, Str9],
        [10, 10, Str10]
    ]
}

このように返ってきます。
クエリは SELECT * FROM ... としてしまうと、ROWIDは返ってきません。

ROWIDを使ってUPDATE

以上をまとめて、最初のコードを以下のように書き換えます。

updateTable.gs
function updateTable(){
  var query;
  var tableId = "1_C...lpL";  // docid

  // Id = 5 の条件で ROWIDを取得する
  query = "SELECT ROWID FROM " + tableId + " WHERE Id = 5";
  var result = FusionTables.Query.sqlGet(query);

  // 変更するテキスト
  var str = "Changed Str";

  // 取得したROWIDを指定してUPDATE
  query = "UPDATE " + tableId + " SET Text = '" + str + "' WHERE ROWID = '" + result.rows[0][0] + "'";

  FusionTables.Query.sql(query);
}

これで無事に Id = 5 のデータをUPDATEすることが出来ました。

単一のデータを更新する際は上記のコードで良いですが、
複数レコードヒットしても1レコードしか更新されないので、
複数データを更新する場合は、更に以下のように書き換えます。

updateTable.gs
function updateTable(){
  var query;
  var tableId = "1_C...lpL";  // docid

  // 4 <= Id <= 7 の条件で ROWIDを取得する
  query = "SELECT ROWID FROM " + tableId + " WHERE Id >= 4 AND Id <= 7";
  var result = FusionTables.Query.sqlGet(query);

  // 変更するテキスト
  var str = "Changed Str";

  // 取得した分のROWIDをループしてクエリを作成
  for(i = 0; i < result.rows.length; i++){
    query = "UPDATE " + tableId + " SET Text = '" + str + "' WHERE ROWID = '" + result.rows[i][0] + "'";
    FusionTables.Query.sql(query);
  }
}

これで無事に複数のデータを更新出来ました。

注意点

ROWIDですが単に行番号というわけではなく、
オートナンバーのフィールドがあるイメージなので、
レコードを削除すると行番号からズレていきます(当たり前ですが…)
やることは少ないと思いますが、行決め打ちで更新する場合は注意が必要です。