すべてのプロダクト
Search
ドキュメントセンター

Lindorm:UPSERT

最終更新日:Jul 07, 2025

UPSERT 構文は、INSERT 構文と UPDATE 構文の組み合わせと同じように機能します。指定された行がすでに存在する場合、UPDATE 構文が実行されます。行が存在しない場合は、INSERT 構文が実行されます。UPSERT 文を実行するときは、プライマリキーとして使用される列を指定する必要があります。UPSERT 構文を使用すると、タイムスタンプ付きの個々の行または複数の行のデータをバッチで挿入できます。この場合、UPSERT 構文は INSERT 構文と同じです。

適用可能なエンジンとバージョン

UPSERT 構文は、LindormTable および LindormTSDB のすべてのバージョンに適用できます。

リレーショナルデータベースの INSERT 操作と Lindorm の UPSERT 操作の比較

Lindorm の UPSERT 操作は、リレーショナルデータベースの INSERT 操作とは異なります。

  • リレーショナルデータベースの INSERT 操作

    指定されたプライマリキーを持つテーブルの場合、ON DUPLICATE KEY 句を指定せずに 2 つの連続した INSERT 操作を実行して同じプライマリキー値を持つデータを書き込むと、2 番目の INSERT 操作は失敗します。この場合、UPDATE 文を明示的に実行してデータを更新するか、2 番目の INSERT 操作で ON DUPLICATE KEY 句を指定する必要があります。

  • Lindorm の INSERT 操作

    • LindormTable:同じプライマリキーを持つデータを書き込むために 2 つの連続した UPSERT 操作を実行すると、2 番目の UPSERT 操作は、エラーを報告することなく、最初の UPSERT 操作によって書き込まれたデータ行を上書きします。この場合、LindormTable は、2 つの操作によって書き込まれた行を異なるバージョンとして保存します。デフォルトでは、SELECT 文を実行してデータ行をクエリすると、行の各列の最新バージョンが返されます。

    • LindormTSDB:同じプライマリキーを持つデータを書き込むために 2 つの連続した UPSERT 操作を実行すると、2 番目の UPSERT 操作は、最初の UPSERT 操作によって書き込まれたデータ行を上書きします。

UPSERT 構文を使用して同じプライマリキーを持つ行を挿入する方法の例については、「同じプライマリキーを持つ行を書き込む」をご参照ください。

構文

upsert_statement   ::= { UPSERT | INSERT } [ hint_expression ] 
                       INTO table_identifier columns_delaration
                       VALUES value_list ( ',' value_list)*
                       [ ON DUPLICATE KEY column_identifier = 
                         value_literal | IGNORE ]
columns_delaration ::=  '(' column_identifier ( ',' column_identifier)* ')'
value_list         ::=  '(' value_expression( ',' value_expression)* ')'

パラメーター

HINT 式 (hint_expression)

HINT 式は、LindormTable でのみサポートされています。

UPSERT 文で _l_ts_ ヒントを使用して、更新または挿入する行のタイムスタンプを指定できます。 _l_ts_ ヒントの詳細については、「ヒント」をご参照ください。

ON DUPLICATE KEY

ON DUPLICATE KEY 句は、LindormTable でのみサポートされています。

ON DUPLICATE KEY 句は、指定された行が存在するかどうかを確認するために使用され、HBase の CHECK AND PUT 操作に似ています。この句は、次のルールに準拠しています。

  • ON DUPLICATE KEY 句の後に UPDATE キーワードを使用して、指定された列の値を更新できます。

    • 指定された行がすでに存在する場合、UPDATE キーワードの後の文が実行され、指定された列の値が更新されます。

    • 指定された行が存在しない場合、データは更新されず、2.7.8 より前の LindormTable ではエラーは報告されません。ただし、LindormTable 2.7.8 以降ではエラーが報告され、VALUES 句のデータがテーブルに挿入されます。

  • ON DUPLICATE KEY 句の後に IGNORE キーワードを使用することもできます。この場合、指定された行がすでに存在する場合、データは更新されず、エラーは報告されません。指定された行が存在しない場合、データはテーブルに書き込まれます。

  • LindormTable 2.7.8 以降では、ON DUPLICATE KEY 句の後に ERROR キーワードを使用できます。この場合、指定された行がすでに存在すると、エラーが報告されます。指定された行が存在しない場合、データはテーブルに書き込まれます。

  • ON DUPLICATE KEY 句は、CONSISTENCY パラメーターが strong に設定されているテーブルにのみ適用できます。 CONSISTENCY パラメーターの詳細については、「テーブル属性 (table_options)」をご参照ください。テーブルの CONSISTENCY パラメーターの値を変更するには、「ALTER TABLE」をご参照ください。

重要

Lindorm SQL 2.8.8.2 以降では、UPSERT 文を実行して現在のタイムスタンプを自動的に挿入する場合、文に NOW() 関数を含めることができます。例:UPSERT INTO tb (id, ts) VALUES (1, NOW()); 。 Lindorm SQL のバージョンの確認方法については、「SQL バージョン」をご参照ください。

次の例では、サンプルテーブル sensor は、次の文を実行することによって作成されます。

CREATE TABLE sensor (
    device_id VARCHAR NOT NULL,
    region VARCHAR NOT NULL,
    time TIMESTAMP NOT NULL,
    temperature DOUBLE,
    humidity BIGINT,
    PRIMARY KEY(device_id, region, time)
)WITH(VERSIONS=2);

テーブルにデータを書き込む

UPSERT INTO sensor(device_id, region, time, temperature, humidity) VALUES('F07A1260','north-cn','2021-04-22 15:33:00',12.1,45);

結果の確認

SELECT * FROM sensor; 文を実行して、データがテーブルに書き込まれたかどうかを確認できます。

特定の列にデータを書き込む

UPSERT INTO sensor(device_id, region, time,temperature) VALUES('F07A1260','north-cn','2021-04-22 15:33:10',13.2);

結果の確認

SELECT * FROM sensor; 文を実行して、データがテーブルに書き込まれたかどうかを確認できます。

文で ON DUPLICATE KEY IGNORE 句を使用してテーブルにデータを書き込む

LindormTable のテーブルにデータを書き込むには、ON DUPLICATE KEY IGNORE 句を使用します。

device_id='F07A1260', region='north-cn', time='2021-04-22 15:33:10', temperature=13.2 で指定された条件を満たす行が存在する場合、データは書き込まれません。行が存在しない場合、データはテーブルに書き込まれます。

UPSERT INTO sensor(device_id,region,time,temperature) VALUES('F07A1260','north-cn','2021-04-22 15:33:10',13.2) ON DUPLICATE KEY IGNORE;

結果の確認

SELECT * FROM sensor; 文を実行して、データがテーブルに書き込まれたかどうかを確認できます。

文で ON DUPLICATE KEY UPDATE 句を使用してテーブルのデータを更新する

LindormTable のテーブルにデータを書き込むには、ON DUPLICATE KEY UPDATE 句を使用します。

  • V2.7.8 より前の LindormTable

    device_id='F07A1260', region='north-cn', time='2021-04-22 15:33:10', temperature=13.2 で指定された条件を満たす行が存在する場合、temperature 列の値は 30 に更新されます。行が存在しない場合、temperature 列の値は更新されず、エラーは報告されません。

    UPSERT INTO sensor(device_id,region,time,temperature) VALUES('F07A1260','north-cn','2021-04-22 15:33:10',13.2) ON DUPLICATE KEY UPDATE temperature = 30;
  • LindormTable 2.7.8 以降

    device_id='F07A1260',region='north-cn',time='2021-04-22 15:33:10',temperature=13.2 で指定された条件を満たす行が存在する場合、temperature 列の値は 30 に更新されます。行が存在しない場合、VALUES 句のデータがテーブルに挿入されます。

    UPSERT INTO sensor(device_id,region,time,temperature) VALUES('F07A1260','north-cn','2021-04-22 15:33:10',13.2) ON DUPLICATE KEY UPDATE temperature = 30;

結果の確認

SELECT * FROM sensor; 文を実行して、データがテーブルに書き込まれたかどうかを確認できます。

文で ON DUPLICATE KEY ERROR 句を使用してテーブルにデータを書き込む

LindormTable 2.7.8 以降でテーブルにデータを書き込むには、ON DUPLICATE KEY ERROR 句を使用します。

device_id='F07A1260', region='north-cn', time='2021-04-22 15:33:10', temperature=13.2 で指定された条件を満たす行が存在する場合、エラーが報告されます。行が存在しない場合、データはテーブルに書き込まれます。

UPSERT INTO sensor(device_id,region,time,temperature) VALUES('F07A1260','north-cn','2021-04-22 15:33:10',13.2) ON DUPLICATE KEY ERROR;

タイムスタンプ付きのデータを書き込む

LindormTable のテーブル sensor にデータ行を書き込み、行のタイムスタンプを 111232 に設定します。

UPSERT /*+ _l_ts_(111232) */ INTO sensor (device_id ,region ,time,temperature) VALUES('F07A1260','north-cn','2021-04-22 15:33:00',12.1);

結果の確認

SELECT * FROM sensor; 文を実行して、データがテーブルに書き込まれたかどうかを確認できます。

複数のデータ行を同時に書き込む

UPSERT INTO sensor (device_id ,region ,time,temperature) VALUES('F07A1260','north-cn','2021-04-22 15:33:20',10.6), ('F07A1261','south-cn','2021-04-22 15:33:00',18.1), ('F07A1261','south-cn','2021-04-22 15:33:10',19.7);

結果の確認

SELECT * FROM sensor; 文を実行して、データがテーブルに書き込まれたかどうかを確認できます。

同じプライマリキーを持つ行を書き込む

UPSERT 文を使用して、LindormTable に同じプライマリキーを持つ 2 つのデータ行を連続して書き込みます。次に、ヒントを使用して、テーブルに書き込まれたデータをクエリします。

説明

LindormTSDB で同じプライマリキーを持つデータを書き込むために 2 つの連続した UPSERT 操作を実行すると、2 番目の UPSERT 操作は、最初の UPSERT 操作によって書き込まれたデータ行を上書きします。

  1. 最初にデータを書き込みます。

    UPSERT INTO sensor(device_id ,region ,time,temperature,humidity) VALUES('F07A1260','north-cn','2021-04-22 15:33:10',13.2,45); 
  2. 最初の操作によって書き込まれたデータをクエリします。

    SELECT * FROM sensor WHERE device_id='F07A1260' AND region='north-cn'; 

    出力例:

    +-----------+----------+-------------------------------+-------------+----------+
    | device_id |  region  |             time              | temperature | humidity |
    +-----------+----------+-------------------------------+-------------+----------+
    | F07A1260  | north-cn | 2021-04-22 15:33:10 +0000 UTC | 13.2        | 45       |
    +-----------+----------+-------------------------------+-------------+----------+
  3. 2 回目にデータを書き込みます。

    UPSERT INTO sensor(device_id ,region ,time,temperature,humidity) VALUES('F07A1260','north-cn','2021-04-22 15:33:10',16.7,52); 
  4. 2 番目の操作によって書き込まれたデータをクエリします。

    SELECT * FROM sensor WHERE device_id='F07A1260' AND region='north-cn'; 

    出力例:

    +-----------+----------+-------------------------------+-------------+----------+
    | device_id |  region  |             time              | temperature | humidity |
    +-----------+----------+-------------------------------+-------------+----------+
    | F07A1260  | north-cn | 2021-04-22 15:33:10 +0000 UTC | 16.7        | 52       |
    +-----------+----------+-------------------------------+-------------+----------+

    2 つの操作の device_id、region、および time プライマリキー列の値は同じです。結果によると、最初の操作によって書き込まれた temperature 列の値は、2 番目の操作によって書き込まれた値によって上書きされます。

  5. _l_versions_ ヒントを使用して、書き込まれたデータのすべてのバージョンをクエリします。

    SELECT /*+ _l_versions_(2)  */ device_id, region, time,temperature,humidity FROM sensor WHERE device_id='F07A1260';

    出力例:

    +-----------+----------+-------------------------------+-------------+----------+
    | device_id |  region  |             time              | temperature | humidity |
    +-----------+----------+-------------------------------+-------------+----------+
    | F07A1260  | north-cn | 2021-04-22 15:33:10 +0000 UTC | 16.7        | 52       |
    | F07A1260  | north-cn | 2021-04-22 15:33:10 +0000 UTC | 13.2        | 45       |
    +-----------+----------+-------------------------------+-------------+----------+

    結果によると、2 つの操作によって書き込まれた値は 2 つのバージョンとして保存されます。