INSERT

テーブルに1つ以上の行を挿入して、テーブルを更新します。テーブルの各列に挿入される値は、明示的に指定するか、クエリの結果にすることができます。

こちらもご参照ください。

INSERT (マルチテーブル)

構文

INSERT [ OVERWRITE ] INTO <target_table> [ ( <target_col_name> [ , ... ] ) ]
       {
         VALUES ( { <value> | DEFAULT | NULL } [ , ... ] ) [ , ( ... ) ]  |
         <query>
       }
Copy

必須パラメーター

target_table

行を挿入するターゲットテーブルを指定します。

VALUES ( value | DEFAULT | NULL [ , ... ] )  [ , ( ... ) ]

ターゲットテーブルの対応する列に挿入する1つ以上の値を指定します。

VALUES 句では、次を指定できます。

  • value: 明示的に指定された値を挿入します。値はリテラルまたは式です。

  • DEFAULT: ターゲットテーブルの対応する列にデフォルト値を挿入します。

  • NULL: NULL 値を挿入します。

句の各値はコンマで区切る必要があります。

句に追加の値セットを指定することにより、複数の行を挿入できます。詳細については、 使用上の注意 および (このトピック内)をご参照ください。

query

対応する列に挿入される値を返す クエリ ステートメントを指定します。これにより、1つ以上のソーステーブルからターゲットテーブルに行を挿入できます。

オプションのパラメーター

OVERWRITE

テーブルに値を挿入する前に、ターゲットテーブルを切り捨てる必要があることを指定します。このオプションを指定しても、テーブルのアクセス制御権限には影響しません。

INSERT OVERWRITE を含むステートメントは、現在のトランザクションのスコープ内で処理できます。これにより、次のようなトランザクションをコミットする DDL ステートメントを回避できます。

DROP TABLE t;
CREATE TABLE t AS SELECT * FROM ... ;
Copy

デフォルト: 値なし(ターゲットテーブルは、挿入を実行する前に切り捨て られない

( target_col_name [ , ... ] )

対応する値が挿入されるターゲットテーブルの1つ以上の列を指定します。指定されたターゲット列の数は、 VALUES 句で指定された値または列の値と一致する必要があります(値がクエリの結果である場合)。

デフォルト: 値なし(ターゲットテーブルの列が すべて 更新されます)。

使用上の注意

  • 単一の INSERT コマンドを使用して、 VALUES 句でコンマで区切られた追加の値セットを指定することにより、テーブルに複数の行を挿入できます。

    たとえば、次の句は3列のテーブルに3行を挿入しますが、最初の2行には値 12、および 3 を、3行目には値 23、および 4 を挿入します。

    VALUES ( 1, 2, 3 ) ,
           ( 1, 2, 3 ) ,
           ( 2, 3, 4 )
    
    Copy
  • INSERT で OVERWRITE オプションを使用するには、 OVERWRITE がテーブル内の既存の記録を削除するため、テーブルに対する DELETE 権限のあるロールを使用する必要があります。

  • VALUES 句で指定できない式もあります。別の方法として、クエリ句で式を指定します。たとえば、次を置き換えることができます。

    INSERT INTO table1 (ID, varchar1, variant1)
        VALUES (4, 'Fourier', PARSE_JSON('{ "key1": "value1", "key2": "value2" }'));
    
    Copy

    使用:

    INSERT INTO table1 (ID, varchar1, variant1)
        SELECT 4, 'Fourier', PARSE_JSON('{ "key1": "value1", "key2": "value2" }');
    
    Copy
  • VALUES 句は16,384行に制限されます。この制限は、単一の INSERT INTO ... VALUES ステートメントと単一の INSERT INTO ... SELECT ... FROM VALUES ステートメントに適用されます。一括データロードを実行するには、 COPY INTO <テーブル> コマンドの使用を検討してください。SELECT ステートメントでの VALUES 句の仕様の詳細については、 VALUES をご参照ください。

  • ハイブリッド・テーブルへのデータ挿入については、 データのロード をご参照ください。

以下の例では、 INSERT コマンドを使用しています。

クエリを使用した単一行挿入

3つの文字列値を日付またはタイムスタンプに変換し、それらを mytable テーブルの単一行に挿入します。

CREATE OR REPLACE TABLE mytable (
  col1 DATE,
  col2 TIMESTAMP_NTZ,
  col3 TIMESTAMP_NTZ);

DESC TABLE mytable;
Copy
+------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
| name | type             | kind   | null? | default | primary key | unique key | check | expression | comment | policy name | privacy domain |
|------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------|
| COL1 | DATE             | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| COL2 | TIMESTAMP_NTZ(9) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| COL3 | TIMESTAMP_NTZ(9) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
+------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
INSERT INTO mytable
  SELECT
    TO_DATE('2013-05-08T23:39:20.123'),
    TO_TIMESTAMP('2013-05-08T23:39:20.123'),
    TO_TIMESTAMP('2013-05-08T23:39:20.123');

SELECT * FROM mytable;
Copy
+------------+-------------------------+-------------------------+
| COL1       | COL2                    | COL3                    |
|------------+-------------------------+-------------------------|
| 2013-05-08 | 2013-05-08 23:39:20.123 | 2013-05-08 23:39:20.123 |
+------------+-------------------------+-------------------------+

前の例と同様ですが、テーブルの最初と3番目の列のみを更新するように指定します。

INSERT INTO mytable (col1, col3)
  SELECT
    TO_DATE('2013-05-08T23:39:20.123'),
    TO_TIMESTAMP('2013-05-08T23:39:20.123');

SELECT * FROM mytable;
Copy
+------------+-------------------------+-------------------------+
| COL1       | COL2                    | COL3                    |
|------------+-------------------------+-------------------------|
| 2013-05-08 | 2013-05-08 23:39:20.123 | 2013-05-08 23:39:20.123 |
| 2013-05-08 | NULL                    | 2013-05-08 23:39:20.123 |
+------------+-------------------------+-------------------------+

明示的に指定された値を使用した複数行挿入

employees テーブルを作成し、 VALUES 句にコンマ区切りのリストで値の提供して、4行のデータを挿入します。

CREATE TABLE employees (
  first_name VARCHAR,
  last_name VARCHAR,
  workphone VARCHAR,
  city VARCHAR,
  postal_code VARCHAR);

INSERT INTO employees
  VALUES
    ('May', 'Franklin', '1-650-249-5198', 'San Francisco', 94115),
    ('Gillian', 'Patterson', '1-650-859-3954', 'San Francisco', 94115),
    ('Lysandra', 'Reeves', '1-212-759-3751', 'New York', 10018),
    ('Michael', 'Arnett', '1-650-230-8467', 'San Francisco', 94116);

SELECT * FROM employees;
Copy
+------------+-----------+----------------+---------------+-------------+
| FIRST_NAME | LAST_NAME | WORKPHONE      | CITY          | POSTAL_CODE |
|------------+-----------+----------------+---------------+-------------|
| May        | Franklin  | 1-650-249-5198 | San Francisco | 94115       |
| Gillian    | Patterson | 1-650-859-3954 | San Francisco | 94115       |
| Lysandra   | Reeves    | 1-212-759-3751 | New York      | 10018       |
| Michael    | Arnett    | 1-650-230-8467 | San Francisco | 94116       |
+------------+-----------+----------------+---------------+-------------+

複数行の挿入では、最初の行のデータ型がガイドとして使用されるため、挿入された値のデータ型が行全体で一貫していることを確認してください。テーブルを作成し、2行を挿入します。

CREATE OR REPLACE TABLE demo_insert_type_mismatch (v VARCHAR);
Copy

最初の挿入は期待通りに機能します。

INSERT INTO demo_insert_type_mismatch (v) VALUES
  ('three'),
  ('four');
Copy
+-------------------------+
| number of rows inserted |
|-------------------------|
|                       2 |
+-------------------------+

2行目の値('d')のデータ型が文字列であり、1行目の値(3)の数値データ型と異なるため、2回目の挿入は失敗します。どちらの値もテーブルの列のデータ型である VARCHAR に 強制 できるにもかかわらず、挿入は失敗します。値 'd' のデータ型が列 v のデータ型と同じでも、挿入は失敗します。

INSERT INTO demo_insert_type_mismatch (v) VALUES
  (3),
  ('d');
Copy
100038 (22018): DML operation to table DEMO_INSERT_TYPE_MISMATCH failed on column V with error: Numeric value 'd' is not recognized

データ型が行全体で一致している場合、挿入は成功し、両方の数値は VARCHAR データ型に強制されます。

INSERT INTO demo_insert_type_mismatch (v) VALUES
  (3),
  (4);
Copy
+-------------------------+
| number of rows inserted |
|-------------------------|
|                       2 |
+-------------------------+

クエリを使用した複数行挿入

contractors テーブルの複数行のデータを employees テーブルに挿入します。

  • worknum 列に市外局番 650 が含まれる行のみを選択します。

  • city 列に NULL 値を挿入します。

SELECT * FROM employees;
Copy
+------------+-----------+----------------+---------------+-------------+
| FIRST_NAME | LAST_NAME | WORKPHONE      | CITY          | POSTAL_CODE |
|------------+-----------+----------------+---------------+-------------|
| May        | Franklin  | 1-650-249-5198 | San Francisco | 94115       |
| Gillian    | Patterson | 1-650-859-3954 | San Francisco | 94115       |
| Lysandra   | Reeves    | 1-212-759-3751 | New York      | 10018       |
| Michael    | Arnett    | 1-650-230-8467 | San Francisco | 94116       |
+------------+-----------+----------------+---------------+-------------+
CREATE TABLE contractors (
  contractor_first VARCHAR,
  contractor_last VARCHAR,
  worknum VARCHAR,
  city VARCHAR,
  zip_code VARCHAR);

INSERT INTO contractors
  VALUES
    ('Bradley', 'Greenbloom', '1-650-445-0676', 'San Francisco', 94110),
    ('Cole', 'Simpson', '1-212-285-8904', 'New York', 10001),
    ('Laurel', 'Slater', '1-650-633-4495', 'San Francisco', 94115);

SELECT * FROM contractors;
Copy
+------------------+-----------------+----------------+---------------+----------+
| CONTRACTOR_FIRST | CONTRACTOR_LAST | WORKNUM        | CITY          | ZIP_CODE |
|------------------+-----------------+----------------+---------------+----------|
| Bradley          | Greenbloom      | 1-650-445-0676 | San Francisco | 94110    |
| Cole             | Simpson         | 1-212-285-8904 | New York      | 10001    |
| Laurel           | Slater          | 1-650-633-4495 | San Francisco | 94115    |
+------------------+-----------------+----------------+---------------+----------+
INSERT INTO employees(first_name, last_name, workphone, city, postal_code)
  SELECT contractor_first, contractor_last, worknum, NULL, zip_code
    FROM contractors
    WHERE CONTAINS(worknum,'650');

SELECT * FROM employees;
Copy
+------------+------------+----------------+---------------+-------------+
| FIRST_NAME | LAST_NAME  | WORKPHONE      | CITY          | POSTAL_CODE |
|------------+------------+----------------+---------------+-------------|
| May        | Franklin   | 1-650-249-5198 | San Francisco | 94115       |
| Gillian    | Patterson  | 1-650-859-3954 | San Francisco | 94115       |
| Lysandra   | Reeves     | 1-212-759-3751 | New York      | 10018       |
| Michael    | Arnett     | 1-650-230-8467 | San Francisco | 94116       |
| Bradley    | Greenbloom | 1-650-445-0676 | NULL          | 94110       |
| Laurel     | Slater     | 1-650-633-4495 | NULL          | 94115       |
+------------+------------+----------------+---------------+-------------+

共通のテーブル式を使用して、 contractors テーブルから employees テーブルに複数行のデータを挿入します。

INSERT INTO employees (first_name, last_name, workphone, city, postal_code)
  WITH cte AS
    (SELECT contractor_first AS first_name,
            contractor_last AS last_name,
            worknum AS workphone,
            city,
            zip_code AS postal_code
       FROM contractors)
  SELECT first_name, last_name, workphone, city, postal_code
    FROM cte;
Copy

ソーステーブルの id 列の INNER JOIN を使用して、2つのテーブル(emp_addremp_ph)の列を3番目のテーブル(emp)に挿入します。

INSERT INTO emp (id, first_name, last_name, city, postal_code, ph)
  SELECT a.id, a.first_name, a.last_name, a.city, a.postal_code, b.ph
    FROM emp_addr a
    INNER JOIN emp_ph b ON a.id = b.id;
Copy

JSON データの複数行挿入

2つの JSON オブジェクトをテーブルの VARIANT 列に挿入します。

CREATE TABLE prospects (column1 VARIANT);

INSERT INTO prospects
  SELECT PARSE_JSON(column1)
  FROM VALUES
  ('{
    "_id": "57a37f7d9e2b478c2d8a608b",
    "name": {
      "first": "Lydia",
      "last": "Williamson"
    },
    "company": "Miralinz",
    "email": "lydia.williamson@miralinz.info",
    "phone": "+1 (914) 486-2525",
    "address": "268 Havens Place, Dunbar, Rhode Island, 02801"
  }')
  , ('{
    "_id": "57a37f7d622a2b1f90698c01",
    "name": {
      "first": "Denise",
      "last": "Holloway"
    },
    "company": "DIGIGEN",
    "email": "denise.holloway@digigen.net",
    "phone": "+1 (979) 587-3021",
    "address": "441 Dover Street, Ada, New Mexico, 87105"
  }');
Copy

OVERWRITE を使用した挿入

この例では、 INSERT と OVERWRITE を使用して、 employees テーブルに新しいレコードが追加された後、 employees から sf_employees テーブルを再構築します。

両方のテーブルの初期データは次のとおりです。

SELECT * FROM employees;
Copy
+------------+-----------+----------------+---------------+-------------+
| FIRST_NAME | LAST_NAME | WORKPHONE      | CITY          | POSTAL_CODE |
|------------+-----------+----------------+---------------+-------------|
| May        | Franklin  | 1-650-111-1111 | San Francisco | 94115       |
| Gillian    | Patterson | 1-650-222-2222 | San Francisco | 94115       |
| Lysandra   | Reeves    | 1-212-222-2222 | New York      | 10018       |
| Michael    | Arnett    | 1-650-333-3333 | San Francisco | 94116       |
+------------+-----------+----------------+---------------+-------------+
SELECT * FROM sf_employees;
Copy
+------------+-----------+----------------+---------------+-------------+
| FIRST_NAME | LAST_NAME | WORKPHONE      | CITY          | POSTAL_CODE |
|------------+-----------+----------------+---------------+-------------|
| Mary       | Smith     | 1-650-999-9999 | San Francisco | 94115       |
+------------+-----------+----------------+---------------+-------------+

このステートメントは、 OVERWRITE 句を使用して sf_employees テーブルに行を挿入します。

INSERT OVERWRITE INTO sf_employees
  SELECT * FROM employees
  WHERE city = 'San Francisco';
Copy

INSERT は OVERWRITE 句を使用しているため、 sf_employees の古い行は消えています。

SELECT * FROM sf_employees;
Copy
+------------+-----------+----------------+---------------+-------------+
| FIRST_NAME | LAST_NAME | WORKPHONE      | CITY          | POSTAL_CODE |
|------------+-----------+----------------+---------------+-------------|
| May        | Franklin  | 1-650-111-1111 | San Francisco | 94115       |
| Gillian    | Patterson | 1-650-222-2222 | San Francisco | 94115       |
| Michael    | Arnett    | 1-650-333-3333 | San Francisco | 94116       |
+------------+-----------+----------------+---------------+-------------+