Posted at

【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ですが単に行番号というわけではなく、

オートナンバーのフィールドがあるイメージなので、

レコードを削除すると行番号からズレていきます(当たり前ですが…)

やることは少ないと思いますが、行決め打ちで更新する場合は注意が必要です。