UPDATE文を使用した表の行の変更

このトピックでは、SQL for Oracle NoSQL DatabaseのUPDATE文を使用して表の行を更新する方法の例を示します。UPDATE文は直接サーバー側の更新を行い、読取り/変更/書込みの更新サイクルを必要としないため、表の行データを効率的に更新できます。

ノート:

UPDATE文を使用して実行できるのは、既存の行の更新のみです。UPDATEを使用して新しい行を作成したり、既存の行を削除することはできません。UPDATE文では一度に1行のみを変更できます。

サンプル・データ

この章の例では、Examplesダウンロード・パッケージに含まれているSQLJSONExamplesスクリプトによってロードされるデータを使用します。このスクリプトの使用方法、ロードされるサンプル・データおよびExamplesダウンロードの詳細は、SQLJSONExamplesスクリプトを参照してください。

フィールド値の変更

最も簡単な例は、Update文のSET句を使用したフィールド値の変更です。JSONのサンプル・データ・セットには、配列と整数のみを含む行があります。これは、行ID 6です。

sql-> mode column
Query output mode is COLUMN
sql-> SELECT * from JSONPersons j WHERE j.id = 6;
 +----+-------------------+
 | id |      person       |
 +----+-------------------+
 |  6 | myarray           |
 |    |            1      |
 |    |            2      |
 |    |            3      |
 |    |            4      |
 |    | mynumber | 5      |
 +----+-------------------+

1 row returned 

次の文を使用して、その行のmynumberの値を変更できます。

sql-> UPDATE JSONPersons j
          SET j.person.mynumber = 100
          WHERE j.id = 6;
 +----------+
 | Column_1 |
 +----------+
 |        1 |
 +----------+

1 row returned
sql-> SELECT * from JSONPersons j WHERE j.id = 6;
 +----+-------------------+
 | id |      person       |
 +----+-------------------+
 |  6 | myarray           |
 |    |            1      |
 |    |            2      |
 |    |            3      |
 |    |            4      |
 |    | mynumber | 100    |
 +----+-------------------+

1 row returned 

前述の例では、Update文から戻された結果があまり有益ではないため、更新結果を表示するためにSelect文を再発行する必要がありました。RETURNING句を使用することで、これを回避できます。これはSelect文とまったく同じように機能します。

sql-> UPDATE JSONPersons j 
          SET j.person.mynumber = 200 
          WHERE j.id = 6
          RETURNING *;
 +----+-------------------+
 | id |      person       |
 +----+-------------------+
 |  6 | myarray           |
 |    |            1      |
 |    |            2      |
 |    |            3      |
 |    |            4      |
 |    | mynumber | 200    |
 +----+-------------------+

1 row returned
sql-> 

SELECT文を使用する場合と同じ方法で、表示される結果をさらに制限およびカスタマイズできます。

sql-> UPDATE JSONPersons j 
          SET j.person.mynumber = 300 
          WHERE j.id = 6
          RETURNING id, j.person.mynumber AS MyNumber;
 +----+---------------------+
 | id |      MyNumber       |
 +----+---------------------+
 |  6 | 300                 |
 +----+---------------------+

1 row returned
sql-> 

通常は、SET句を使用して非JSONフィールドの値を更新できます。ただし、主キーであるフィールドは変更できません。次に例を示します。

sql-> UPDATE JSONPersons j 
          SET j.id = 1000
          WHERE j.id = 6
          RETURNING *;
Error handling command UPDATE JSONPersons j
SET j.id = 1000
WHERE j.id = 6
RETURNING *: Error: at (2, 4) Cannot update a primary key column
Usage:

Unknown statement

sql-> 

配列値の変更

Update文のADD句を使用して、配列に要素を追加します。既存の配列要素の値を変更するには、SET句を使用します。配列から要素を削除するには、REMOVE句を使用します。

配列への要素の追加

ADD句では、操作する配列の位置を指定し、その後に配列内のその位置に設定する値を指定する必要があります。設定した索引値が0または負の数値の場合、指定した値が配列の先頭に挿入されます。

索引位置を指定しない場合、指定した配列値は配列の末尾に追加されます。

sql-> SELECT * from JSONPersons j WHERE j.id = 6;
 +----+-------------------+
 | id |      person       |
 +----+-------------------+
 |  6 | myarray           |
 |    |            1      |
 |    |            2      |
 |    |            3      |
 |    |            4      |
 |    | mynumber | 300    |
 +----+-------------------+

1 row returned
sql-> UPDATE JSONPersons j
          ADD j.person.myarray 0 50,
          ADD j.person.myarray 100
          WHERE j.id = 6
          RETURNING *;
 +----+-------------------+
 | id |      person       |
 +----+-------------------+
 |  6 | myarray           |
 |    |            50     |
 |    |            1      |
 |    |            2      |
 |    |            3      |
 |    |            4      |
 |    |            100    |
 |    | mynumber | 300    |
 +----+-------------------+

1 row returned
sql-> 

前述の問合せでは、複数のADD句が使用されていることに注意してください。

配列のサイズより大きい配列位置を指定した場合でも、配列値は配列の末尾に追加されます。任意の大きい数値を指定するか、またはsize()関数を使用できます。

sql-> UPDATE JSONPersons j
          ADD j.person.myarray (size(j.person.myarray) + 1) 400
          WHERE j.id = 6
          RETURNING *;
 +----+-------------------+
 | id |      person       |
 +----+-------------------+
 |  6 | myarray           |
 |    |            50     |
 |    |            1      |
 |    |            2      |
 |    |            3      |
 |    |            4      |
 |    |            100    |
 |    |            400    |
 |    | mynumber | 300    |
 +----+-------------------+

1 row returned
sql-> 

組込みのseq_concat()関数を使用して、配列に値を追加できます。

sql-> UPDATE JSONPersons j
          ADD j.person.myarray seq_concat(66, 77, 88)
          WHERE j.id = 6
          RETURNING *;
 +----+-------------------+
 | id |      person       |
 +----+-------------------+
 |  6 | myarray           |
 |    |            50     |
 |    |            1      |
 |    |            2      |
 |    |            3      |
 |    |            4      |
 |    |            100    |
 |    |            400    |
 |    |            66     |
 |    |            77     |
 |    |            88     |
 |    | mynumber | 300    |
 +----+-------------------+

1 row returned
sql-> 

0と配列のサイズの間の配列位置を指定した場合、指定した値は、配列内で指定した位置のに挿入されます。正しい位置を指定するために、0からカウントしてください。

UPDATE JSONPersons j
    ADD j.person.myarray 3 250
    WHERE j.id = 6
    RETURNING *;
 +----+-------------------+
 | id |      person       |
 +----+-------------------+
 |  6 | myarray           |
 |    |            50     |
 |    |            1      |
 |    |            2      |
 |    |            250    |
 |    |            3      |
 |    |            4      |
 |    |            100    |
 |    |            400    |
 |    |            66     |
 |    |            77     |
 |    |            88     |
 |    | mynumber | 300    |
 +----+-------------------+

1 row returned
sql-> 

配列内の既存要素の変更

配列内の既存の値を変更するには、SET句を使用し、[]で値の位置を指定します。値の位置を指定するには、0からカウントします。

sql-> UPDATE JSONPersons j
          SET j.person.myarray[3] = 1000
          WHERE j.id = 6
          RETURNING *;
 +----+-------------------+
 | id |      person       |
 +----+-------------------+
 |  6 | myarray           |
 |    |            50     |
 |    |            1      |
 |    |            2      |
 |    |            1000   |
 |    |            3      |
 |    |            4      |
 |    |            100    |
 |    |            400    |
 |    |            66     |
 |    |            77     |
 |    |            88     |
 |    | mynumber | 300    |
 +----+-------------------+

1 row returned
sql-> 

配列からの要素の削除

配列から既存の要素を削除するには、REMOVE句を使用します。これを行うには、削除する要素の配列内での位置を指定する必要があります。値の位置を指定するには、0からカウントします。

sql-> UPDATE JSONPersons j
          REMOVE j.person.myarray[3]
          WHERE j.id = 6
          RETURNING *;
 +----+-------------------+
 | id |      person       |
 +----+-------------------+
 |  6 | myarray           |
 |    |            50     |
 |    |            1      |
 |    |            2      |
 |    |            3      |
 |    |            4      |
 |    |            100    |
 |    |            400    |
 |    |            66     |
 |    |            77     |
 |    |            88     |
 |    | mynumber | 300    |
 +----+-------------------+

1 row returned
sql-> 

式を使用して配列の位置を指定できます。たとえば、このサンプル・データでは、一部のレコードに電話番号の配列が含まれ、それらの電話番号の一部は仕事用の番号です。

sql-> SELECT * FROM JSONPersons j WHERE j.id = 3;
 +----+---------------------------------------------+
 | id |                   person                    |
 +----+---------------------------------------------+
 |  3 | address                                     |
 |    |     city         | Middleburg               |
 |    |     phones                                  |
 |    |         areacode | 305                      |
 |    |         number   | 1234079                  |
 |    |         type     | work                     |
 |    |                                             |
 |    |         areacode | 305                      |
 |    |         number   | 2066401                  |
 |    |         type     | home                     |
 |    |     state        | FL                       |
 |    |     street       | 187 Aspen Drive          |
 |    | age              | 38                       |
 |    | connections                                 |
 |    |                    1                        |
 |    |                    4                        |
 |    |                    2                        |
 |    | expenses                                    |
 |    |     food         | 2000                     |
 |    |     gas          | 10                       |
 |    |     travel       | 700                      |
 |    | firstname        | John                     |
 |    | income           | 100000000                |
 |    | lastLogin        | 2016-11-29T08:21:35.4971 |
 |    | lastname         | Morgan                   |
 +----+---------------------------------------------+

1 row returned
sql-> 

2つの方法のいずれかで、配列から仕事用の番号を削除できます。1つ目は、配列内の位置(位置0)を直接指定する方法ですが、この場合、一度に削除できる要素は1つのみです。仕事用の番号をすべて削除する場合は、$element変数を使用します。これを説明するために、まず、配列に仕事用の番号を追加します。

sql-> UPDATE JSONPersons j
          ADD j.person.address.phones 0 
          {"type":"work", "areacode":415, "number":9998877}
          WHERE j.id = 3
          RETURNING *;
 +----+---------------------------------------------+
 | id |                   person                    |
 +----+---------------------------------------------+
 |  3 | address                                     |
 |    |     city         | Middleburg               |
 |    |     phones                                  |
 |    |         areacode | 415                      |
 |    |         number   | 9998877                  |
 |    |         type     | work                     |
 |    |                                             |
 |    |         areacode | 305                      |
 |    |         number   | 1234079                  |
 |    |         type     | work                     |
 |    |                                             |
 |    |         areacode | 305                      |
 |    |         number   | 2066401                  |
 |    |         type     | home                     |
 |    |     state        | FL                       |
 |    |     street       | 187 Aspen Drive          |
 |    | age              | 38                       |
 |    | connections                                 |
 |    |                    1                        |
 |    |                    4                        |
 |    |                    2                        |
 |    | expenses                                    |
 |    |     food         | 2000                     |
 |    |     gas          | 10                       |
 |    |     travel       | 700                      |
 |    | firstname        | John                     |
 |    | income           | 100000000                |
 |    | lastLogin        | 2016-11-29T08:21:35.4971 |
 |    | lastname         | Morgan                   |
 +----+---------------------------------------------+

1 row returned
sql-> 

これで、次のようにして仕事用の番号をすべて削除できます。

sql-> UPDATE JSONPersons j
          REMOVE j.person.address.phones[$element.type = "work"]
          WHERE j.id = 3
          RETURNING *;
 +----+---------------------------------------------+
 | id |                   person                    |
 +----+---------------------------------------------+
 |  3 | address                                     |
 |    |     city         | Middleburg               |
 |    |     phones                                  |
 |    |         areacode | 305                      |
 |    |         number   | 2066401                  |
 |    |         type     | home                     |
 |    |     state        | FL                       |
 |    |     street       | 187 Aspen Drive          |
 |    | age              | 38                       |
 |    | connections                                 |
 |    |                    1                        |
 |    |                    4                        |
 |    |                    2                        |
 |    | expenses                                    |
 |    |     food         | 2000                     |
 |    |     gas          | 10                       |
 |    |     travel       | 700                      |
 |    | firstname        | John                     |
 |    | income           | 100000000                |
 |    | lastLogin        | 2016-11-29T08:21:35.4971 |
 |    | lastname         | Morgan                   |
 +----+---------------------------------------------+

1 row returned
sql-> 

マップ値の変更

新しいフィールドをマップに書き込むには、PUT句を使用します。PUT句を使用して、既存のマップ値を変更することもできます。マップ・フィールドを削除するには、REMOVE句を使用します。

たとえば、サンプル・データの次の2行を考えてみます。

sql-> SELECT * FROM JSONPersons j WHERE j.id = 6 OR j.id = 3;
 +----+---------------------------------------------+
 | id |                   person                    |
 +----+---------------------------------------------+
 |  3 | address                                     |
 |    |     city         | Middleburg               |
 |    |     phones                                  |
 |    |         areacode | 305                      |
 |    |         number   | 2066401                  |
 |    |         type     | home                     |
 |    |     state        | FL                       |
 |    |     street       | 187 Aspen Drive          |
 |    | age              | 38                       |
 |    | connections                                 |
 |    |                    1                        |
 |    |                    4                        |
 |    |                    2                        |
 |    | expenses                                    |
 |    |     food         | 2000                     |
 |    |     gas          | 10                       |
 |    |     travel       | 700                      |
 |    | firstname        | John                     |
 |    | income           | 100000000                |
 |    | lastLogin        | 2016-11-29T08:21:35.4971 |
 |    | lastname         | Morgan                   |
 +----+---------------------------------------------+
 |  6 | myarray                                     |
 |    |                    50                       |
 |    |                    1                        |
 |    |                    2                        |
 |    |                    3                        |
 |    |                    4                        |
 |    |                    100                      |
 |    |                    400                      |
 |    |                    66                       |
 |    |                    77                       |
 |    |                    88                       |
 |    | mynumber         | 300                      |
 +----+---------------------------------------------+

 2 rows returned
 sql-> 

これらの2行はまったく似ていません。行3には個人に関する情報が含まれ、行6には基本的にランダムなデータが含まれています。このようになるのは、person列が強い型付けではないJSON型であるためです。ただし、JSON列はマップと同様に操作するため、行6をマップとして変更し、この行を修正できます。

マップからの要素の削除

最初に、行6から2つの既存要素(myarrayおよびmynumber)を削除します。そのために、単一のUPDATE文を使用して、カンマで区切られた複数のupdate句を実行します。

sql-> UPDATE JSONPersons j
          REMOVE j.person.myarray,
          REMOVE j.person.mynumber
          WHERE j.id = 6
          RETURNING *;
 +----+-----------------+
 | id |     person      |
 +----+-----------------+
 |  6 |                 |
 +----+-----------------+

1 row returned
sql-> 

マップへの要素の追加

次に、個人データをこの表の行に追加します。単一のPUT句でマップ全体を指定し、単一のUPDATE文を使用してこの操作を実行できますが、説明のために、複数のステップに分けて行います。

最初に、個人の名前を指定します。ここでは、複数の要素を持つマップを指定する単一のPUT句を使用します。

sql-> UPDATE JSONPersons j
          PUT j.person {"firstname" : "Wendy",
                        "lastname" : "Purvis"}
          WHERE j.id = 6
          RETURNING *;
 +----+--------------------+
 | id |       person       |
 +----+--------------------+
 |  6 | firstname | Wendy  |
 |    | lastname  | Purvis |
 +----+--------------------+

1 row returned
sql-> 

次に、単一のUPDATE文で複数のPUT句を使用して、age、connections、expenses、incomeおよびlastLoginフィールドを指定します。

sql-> UPDATE JSONPersons j
          PUT j.person {"age" : 43},
          PUT j.person {"connections" : [2,3]},
          PUT j.person {"expenses" : {"food" : 1100,
                                      "books" : 210, 
                                      "travel" : 50}},
          PUT j.person {"income" : 80000},
          PUT j.person {"lastLogin" : "2017-06-29T16:12:35.0285"}
          WHERE j.id = 6
          RETURNING *;
 +----+----------------------------------------+
 | id |                 person                 |
 +----+----------------------------------------+
 |  6 | age         | 43                       |
 |    | connections                            |
 |    |               2                        |
 |    |               3                        |
 |    | expenses                               |
 |    |     books   | 210                      |
 |    |     food    | 1100                     |
 |    |     travel  | 50                       |
 |    | firstname   | Wendy                    |
 |    | income      | 80000                    |
 |    | lastLogin   | 2017-06-29T16:12:35.0285 |
 |    | lastname    | Purvis                   |
 +----+----------------------------------------+

1 row returned
sql-> 

まだ住所が必要です。この場合も、単一のPUT句を使用して実行できますが、説明のために複数の句を使用します。最初のPUTによってaddress要素が作成され、これは値としてマップを使用します。2番目のPUTでは、addressマップに要素が追加されます。

sql-> UPDATE JSONPersons j
        PUT j.person {"address" : {"street" : "479 South Way Dr"}},
        PUT j.person.address {"city" : "St. Petersburg",
                              "state" : "FL"}
        WHERE j.id = 6
        RETURNING *;
 +----+----------------------------------------+
 | id |                 person                 |
 +----+----------------------------------------+
 |  6 | address                                |
 |    |     city    | St. Petersburg           |
 |    |     state   | FL                       |
 |    |     street  | 479 South Way Dr         |
 |    | age         | 43                       |
 |    | connections                            |
 |    |               2                        |
 |    |               3                        |
 |    | expenses                               |
 |    |     books   | 210                      |
 |    |     food    | 1100                     |
 |    |     travel  | 50                       |
 |    | firstname   | Wendy                    |
 |    | income      | 80000                    |
 |    | lastLogin   | 2017-06-29T16:12:35.0285 |
 |    | lastname    | Purvis                   |
 +----+----------------------------------------+

1 row returned
sql-> 

最後に、この個人の電話番号を指定します。これらはマップの配列として指定されます。

sql-> UPDATE JSONPersons j
          PUT j.person.address {"phones" : 
                 [{"type":"work", "areacode":727, "number":8284321},
                  {"type":"home", "areacode":727, "number":5710076},
                  {"type":"mobile", "areacode":727, "number":8913080}
                 ]
                                }
          WHERE j.id = 6
          RETURNING *;
 +----+---------------------------------------------+
 | id |                   person                    |
 +----+---------------------------------------------+
 |  6 | address                                     |
 |    |     city         | St. Petersburg           |
 |    |     phones                                  |
 |    |         areacode | 727                      |
 |    |         number   | 8284321                  |
 |    |         type     | work                     |
 |    |                                             |
 |    |         areacode | 727                      |
 |    |         number   | 5710076                  |
 |    |         type     | home                     |
 |    |                                             |
 |    |         areacode | 727                      |
 |    |         number   | 8913080                  |
 |    |         type     | mobile                   |
 |    |     state        | FL                       |
 |    |     street       | 479 South Way Dr         |
 |    | age              | 43                       |
 |    | connections                                 |
 |    |                    2                        |
 |    |                    3                        |
 |    | expenses                                    |
 |    |     books        | 210                      |
 |    |     food         | 1100                     |
 |    |     travel       | 50                       |
 |    | firstname        | Wendy                    |
 |    | income           | 80000                    |
 |    | lastLogin        | 2017-06-29T16:12:35.0285 |
 |    | lastname         | Purvis                   |
 +----+---------------------------------------------+

1 row returned
sql-> 

既存のマップ要素の更新

マップ内の既存要素を更新するには、マップに新しい要素を追加する場合とまったく同じ方法でPUT句を使用します。たとえば、lastLogin時間を更新するには、次のようにします。

sql-> UPDATE JSONPersons j
          PUT j.person {"lastLogin" : "2017-06-29T20:36:04.9661"}
          WHERE j.id = 6
          RETURNING *;
 +----+---------------------------------------------+
 | id |                   person                    |
 +----+---------------------------------------------+
 |  6 | address                                     |
 |    |     city         | St. Petersburg           |
 |    |     phones                                  |
 |    |         areacode | 727                      |
 |    |         number   | 8284321                  |
 |    |         type     | work                     |
 |    |                                             |
 |    |         areacode | 727                      |
 |    |         number   | 5710076                  |
 |    |         type     | home                     |
 |    |                                             |
 |    |         areacode | 727                      |
 |    |         number   | 8913080                  |
 |    |         type     | mobile                   |
 |    |     state        | FL                       |
 |    |     street       | 479 South Way Dr         |
 |    | age              | 43                       |
 |    | connections                                 |
 |    |                    2                        |
 |    |                    3                        |
 |    | expenses                                    |
 |    |     books        | 210                      |
 |    |     food         | 1100                     |
 |    |     travel       | 50                       |
 |    | firstname        | Wendy                    |
 |    | income           | 80000                    |
 |    | lastLogin        | 2017-06-29T20:36:04.9661 |
 |    | lastname         | Purvis                   |
 +----+---------------------------------------------+

1 row returned
sql-> 

または、SET句を使用することもできます。

sql-> UPDATE JSONPersons j
          SET j.person.lastLogin = "2017-06-29T20:38:56.2751"
          WHERE j.id = 6
          RETURNING *;
 +----+---------------------------------------------+
 | id |                   person                    |
 +----+---------------------------------------------+
 |  6 | address                                     |
 |    |     city         | St. Petersburg           |
 |    |     phones                                  |
 |    |         areacode | 727                      |
 |    |         number   | 8284321                  |
 |    |         type     | work                     |
 |    |                                             |
 |    |         areacode | 727                      |
 |    |         number   | 5710076                  |
 |    |         type     | home                     |
 |    |                                             |
 |    |         areacode | 727                      |
 |    |         number   | 8913080                  |
 |    |         type     | mobile                   |
 |    |     state        | FL                       |
 |    |     street       | 479 South Way Dr         |
 |    | age              | 43                       |
 |    | connections                                 |
 |    |                    2                        |
 |    |                    3                        |
 |    | expenses                                    |
 |    |     books        | 210                      |
 |    |     food         | 1100                     |
 |    |     travel       | 50                       |
 |    | firstname        | Wendy                    |
 |    | income           | 80000                    |
 |    | lastLogin        | 2017-06-29T20:38:56.2751 |
 |    | lastname         | Purvis                   |
 +----+---------------------------------------------+

1 row returned
sql-> 

タイムスタンプを現在時刻に設定する場合は、current_time()組込み関数を使用します。

sql-> UPDATE JSONPersons j
          SET j.person.lastLogin = cast(current_time() AS String)
          WHERE j.id = 6
          RETURNING *;
 +----+--------------------------------------------+
 | id |                   person                   |
 +----+--------------------------------------------+
 |  6 | address                                    |
 |    |     city         | St. Petersburg          |
 |    |     phones                                 |
 |    |         areacode | 727                     |
 |    |         number   | 8284321                 |
 |    |         type     | work                    |
 |    |                                            |
 |    |         areacode | 727                     |
 |    |         number   | 5710076                 |
 |    |         type     | home                    |
 |    |                                            |
 |    |         areacode | 727                     |
 |    |         number   | 8913080                 |
 |    |         type     | mobile                  |
 |    |     state        | FL                      |
 |    |     street       | 479 South Way Dr        |
 |    | age              | 43                      |
 |    | connections                                |
 |    |                    2                       |
 |    |                    3                       |
 |    | expenses                                   |
 |    |     books        | 210                     |
 |    |     food         | 1100                    |
 |    |     travel       | 50                      |
 |    | firstname        | Wendy                   |
 |    | income           | 80000                   |
 |    | lastLogin        | 2017-06-29T04:40:15.917 |
 |    | lastname         | Purvis                  |
 +----+--------------------------------------------+

1 row returned
sql-> 

マップ内の要素が配列の場合、配列の場合と同様に変更できます。次に例を示します。

sql-> UPDATE JSONPersons j
          ADD j.person.connections seq_concat(1, 4)
          WHERE j.id = 6
          RETURNING *;
 +----+---------------------------------------------+
 | id |                   person                    |
 +----+---------------------------------------------+
 |  6 | address                                     |
 |    |     city         | St. Petersburg           |
 |    |     phones                                  |
 |    |         areacode | 727                      |
 |    |         number   | 8284321                  |
 |    |         type     | work                     |
 |    |                                             |
 |    |         areacode | 727                      |
 |    |         number   | 5710076                  |
 |    |         type     | home                     |
 |    |                                             |
 |    |         areacode | 727                      |
 |    |         number   | 8913080                  |
 |    |         type     | mobile                   |
 |    |     state        | FL                       |
 |    |     street       | 479 South Way Dr         |
 |    | age              | 43                       |
 |    | connections                                 |
 |    |                    2                        |
 |    |                    3                        |
 |    |                    1                        |
 |    |                    4                        |
 |    | expenses                                    |
 |    |     books        | 210                      |
 |    |     food         | 1100                     |
 |    |     travel       | 50                       |
 |    | firstname        | Wendy                    |
 |    | income           | 80000                    |
 |    | lastLogin        | 2017-06-29T04:40:15.917  |
 |    | lastname         | Purvis                   |
 +----+---------------------------------------------+

1 row returned 

要素が配列とマップのいずれであるかが不明な場合は、同じUPDATE文内でADDとPUTの両方を使用できます。次に例を示します。

sql-> UPDATE JSONPersons j
          ADD j.person.connections seq_concat(5, 7),
          PUT j.person.connections seq_concat(5, 7)
          WHERE j.id = 6
          RETURNING *;
 +----+---------------------------------------------+
 | id |                   person                    |
 +----+---------------------------------------------+
 |  6 | address                                     |
 |    |     city         | St. Petersburg           |
 |    |     phones                                  |
 |    |         areacode | 727                      |
 |    |         number   | 8284321                  |
 |    |         type     | work                     |
 |    |                                             |
 |    |         areacode | 727                      |
 |    |         number   | 5710076                  |
 |    |         type     | home                     |
 |    |                                             |
 |    |         areacode | 727                      |
 |    |         number   | 8913080                  |
 |    |         type     | mobile                   |
 |    |     state        | FL                       |
 |    |     street       | 479 South Way Dr         |
 |    | age              | 43                       |
 |    | connections                                 |
 |    |                    2                        |
 |    |                    3                        |
 |    |                    1                        |
 |    |                    4                        |
 |    |                    5                        |
 |    |                    7                        |
 |    | expenses                                    |
 |    |     books        | 210                      |
 |    |     food         | 1100                     |
 |    |     travel       | 50                       |
 |    | firstname        | Wendy                    |
 |    | income           | 80000                    |
 |    | lastLogin        | 2017-06-29T04:40:15.917  |
 |    | lastname         | Purvis                   |
 +----+---------------------------------------------+

1 row returned 

要素が配列の場合はADDが適用され、PUTは機能しません。マップの場合はPUTが適用され、ADDは機能しません。この例では要素が配列であるため、ADDが適用されます。

存続時間値の管理

存続時間(TTL)値は、データが期限切れになるまでの、表内での存続時間を示します。期限切れになったデータは、問合せの一部として戻されなくなります。

デフォルトTTLの値は、表が最初に定義されるときに、表レベルまたは行レベルのいずれかで設定できます。UPDATE文を使用して、単一行のTTL値を変更できます。

remaining_hours()remaining_days()またはexpiration_time()組込み関数を使用して、行のTTL値を確認できます。これらのTTL関数には、入力として行が必要です。これを行うには、表の別名の一部として$を使用します。これにより、表の別名が行変数として機能するようになります。

sql-> SELECT remaining_days($j) AS Expires 
    FROM JSONPersons $j WHERE id = 6;
 +---------+
 | Expires |
 +---------+
 |      -1 |
 +---------+

1 row returned
sql-> 

この問合せは-1を戻します。これは、行に有効期限がないことを意味します。UPDATE文でset TTL句を使用して、行の有効期限を指定できます。この句は、現在の有効期限からのオフセットを指定して新規TTLを計算します。行が期限切れにならない場合、現在の有効期限は1970-01-01T00:00:00.000です。set TTLに指定する値には、HOURSまたはDAYSのいずれかの単位を指定する必要があります。

sql-> UPDATE JSONPersons $j
          SET TTL 1 DAYS
          WHERE id = 6
          RETURNING remaining_days($j) AS Expires;
 +---------+
 | Expires |
 +---------+
 |       1 |
 +---------+

1 row returned
sql-> 

新しい有効期限を確認するには、組込みのexpiration_time()関数を使用します。1日の境界に基づいて有効期限を指定しているため、行は翌日の午前0時に期限切れになります(有効期限が切上げられます)。

sql-> SELECT current_time() AS Now, 
    expiration_time($j) AS Expires 
    FROM JSONPersons $j WHERE id = 6;
 +-------------------------+-------------------------+
 |           Now           |         Expires         |
 +-------------------------+-------------------------+
 | 2017-07-03T21:56:47.778 | 2017-07-05T00:00:00.000 |
 +-------------------------+-------------------------+

1 row returned
sql-> 

TTLをオフにして、行が期限切れにならないようにするには、HOURSまたはDAYSのいずれかを単位として使用して、負の値を指定します。

sql-> UPDATE JSONPersons $j
          SET TTL -1 DAYS
          WHERE id = 6
          RETURNING remaining_days($j) AS Expires;
 +---------+
 | Expires |
 +---------+
 |       0 |
 +---------+

1 row returned
sql-> 

RETURNING句で0日の値が指定されていることに注意してください。これは、行が期限切れにならないことを示します。さらに、SELECT文を使用してremaining_days()を確認すると、この場合も、行が期限切れにならないことを示す負の値が表示されます。

sql-> SELECT remaining_days($j) AS Expires 
    FROM JSONPersons $j WHERE id = 6;
 +---------+
 | Expires |
 +---------+
 |      -1 |
 +---------+

1 row returned
sql-> 

読取り-変更-書込みサイクルの回避

UPDATE文の重要な点は、値を更新するためにその値を読み取る必要がないことです。かわりに、値を取得する(読み取る)ことなく、ストア内で直接値を変更できます。そのためには、$変数を使用して変更する値を参照します。

たとえば、JSONPersonsに次のような行があるとします。

sql-> SELECT * FROM JSONPersons WHERE id=6;
 +----+--------------------------------------------+
 | id |                   person                   |
 +----+--------------------------------------------+
 |  6 | address                                    |
 |    |     city         | St. Petersburg          |
 |    |     phones                                 |
 |    |         areacode | 727                     |
 |    |         number   | 8284321                 |
 |    |         type     | work                    |
 |    |                                            |
 |    |         areacode | 727                     |
 |    |         number   | 5710076                 |
 |    |         type     | home                    |
 |    |                                            |
 |    |         areacode | 727                     |
 |    |         number   | 8913080                 |
 |    |         type     | mobile                  |
 |    |     state        | FL                      |
 |    |     street       | 479 South Way Dr        |
 |    | age              | 43                      |
 |    | connections                                |
 |    |                    2                       |
 |    |                    3                       |
 |    |                    1                       |
 |    |                    4                       |
 |    | expenses                                   |
 |    |     books        | 210                     |
 |    |     food         | 1100                    |
 |    |     travel       | 50                      |
 |    | firstname        | Wendy                   |
 |    | income           | 80000                   |
 |    | lastLogin        | 2017-07-25T22:50:06.482 |
 |    | lastname         | Purvis                  |
 +----+--------------------------------------------+

1 row returned 

$を参照することで、person.expenses.booksフィールドの値を取得せずに更新できます。次の文では、ストアに対する読取りが実行されません。かわりに、書込み操作がストアで直接実行されます。

sql-> UPDATE JSONPersons j
   ->     SET j.person.expenses.books = $ + 100
   ->     WHERE id = 6;
 +----------------+
 | NumRowsUpdated |
 +----------------+
 |              1 |
 +----------------+

1 row returned 

booksのexpenses値が実際に100増加していることを確認するために、2番目のSELECT文を実行します。

sql-> SELECT * FROM JSONPersons WHERE id=6;
 +----+--------------------------------------------+
 | id |                   person                   |
 +----+--------------------------------------------+
 |  6 | address                                    |
 |    |     city         | St. Petersburg          |
 |    |     phones                                 |
 |    |         areacode | 727                     |
 |    |         number   | 8284321                 |
 |    |         type     | work                    |
 |    |                                            |
 |    |         areacode | 727                     |
 |    |         number   | 5710076                 |
 |    |         type     | home                    |
 |    |                                            |
 |    |         areacode | 727                     |
 |    |         number   | 8913080                 |
 |    |         type     | mobile                  |
 |    |     state        | FL                      |
 |    |     street       | 479 South Way Dr        |
 |    | age              | 43                      |
 |    | connections                                |
 |    |                    2                       |
 |    |                    3                       |
 |    |                    1                       |
 |    |                    4                       |
 |    | expenses                                   |
 |    |     books        | 310                     |
 |    |     food         | 1100                    |
 |    |     travel       | 50                      |
 |    | firstname        | Wendy                   |
 |    | income           | 80000                   |
 |    | lastLogin        | 2017-07-25T22:50:06.482 |
 |    | lastname         | Purvis                  |
 +----+--------------------------------------------+

1 row returned