INSERT¶
通过在表中插入一行或多行来更新表。插入到表中每个列中的值可以是显式指定的,也可以是查询的结果。
- 另请参阅:
语法¶
INSERT [ OVERWRITE ] INTO <target_table> [ ( <target_col_name> [ , ... ] ) ]
{
VALUES ( { <value> | DEFAULT | NULL } [ , ... ] ) [ , ( ... ) ] |
<query>
}
必填参数¶
target_table
指定要在其中插入行的目标表。
VALUES ( value | DEFAULT | NULL [ , ... ] ) [ , ( ... ) ]
指定要插入到目标表的相应列中的一个或多个值。
在
VALUES
子句中,可以指定以下值:value
:插入显式指定的值。该值可以是字面量或表达式。DEFAULT
:插入目标表中相应列的默认值。NULL
:插入NULL
值。
该子句中的每个值都必须用逗号分隔。
query
指定一个 查询 语句,该语句返回要插入到相应列中的值。这允许您将行从一个或多个源表插入到目标表中。
可选参数¶
OVERWRITE
指定在将值插入到表中之前应截断目标表。请注意,指定此选项不会影响对表的访问控制权限。
带
OVERWRITE
的 INSERT 语句可以在当前事务的作用域内进行处理,从而避免提交事务的 DDL 语句,例如:DROP TABLE t; CREATE TABLE t AS SELECT * FROM ... ;
默认值:无值(在执行插入之前 不会 截断目标表)。
( target_col_name [ , ... ] )
指定目标表中的一列或多列,在其中插入对应的值。指定的目标列数必须与
VALUES
子句中指定的值数或列数(如果这些值是查询的结果)匹配。默认值:无值(目标表中的 所有 列都会更新)。
使用说明¶
使用单个 INSERT 命令,您可以通过在
VALUES
子句中指定以逗号分隔的其他值集,将多行插入到表中。例如,以下子句将在包含 3 列的表中插入 3 行,前两行中插入值
1
、2
和3
,第三行中插入值2
、3
和4
:VALUES ( 1, 2, 3 ) , ( 1, 2, 3 ) , ( 2, 3, 4 )
要使用 INSERT 上的 OVERWRITE 选项,您必须使用对表具有 DELETE 权限的角色,因为 OVERWRITE 将删除表中的现有记录。
某些表达式不能在 VALUES 子句中指定。作为替代方法,可以在查询子句中指定表达式。例如,您可以将以下内容:
INSERT INTO table1 (ID, varchar1, variant1) VALUES (4, 'Fourier', PARSE_JSON('{ "key1": "value1", "key2": "value2" }'));
替换为:
INSERT INTO table1 (ID, varchar1, variant1) SELECT 4, 'Fourier', PARSE_JSON('{ "key1": "value1", "key2": "value2" }');
VALUES 子句限制为 16,384 行。此限制适用于单个 INSERT INTO ...VALUES 语句和单个 INSERT INTO ...SELECT ...FROM VALUES 语句。考虑使用 COPY INTO <table> 命令执行批量数据加载。有关在 SELECT 语句中使用 VALUES 子句的更多信息,请参阅 VALUES。
示例¶
使用查询进行单行插入¶
将三个字符串值转换为日期或时间戳,并将它们插入到 mytable
表中的单行中:
DESC TABLE mytable; +------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+ | name | type | kind | null? | default | primary key | unique key | check | expression | comment | |------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------| | COL1 | DATE | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | | COL2 | TIMESTAMP_NTZ(9) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | | COL3 | TIMESTAMP_NTZ(9) | COLUMN | Y | NULL | N | N | 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; +------------+-------------------------+-------------------------+ | COL1 | COL2 | COL3 | |------------+-------------------------+-------------------------| | 2013-05-08 | 2013-05-08 23:39:20.123 | 2013-05-08 23:39:20.123 | +------------+-------------------------+-------------------------+
与前面的示例类似,但指定仅更新表中的第一列和第三列:
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; +------------+-------------------------+-------------------------+ | 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 | +------------+-------------------------+-------------------------+
使用显式指定的值进行多行插入¶
通过在 VALUES
子句中以逗号分隔的列表中提供两组值,将两行数据插入到 employees
表中:
SELECT * FROM employees; +------------+-----------+----------------+---------------+-------------+ | 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 | +------------+-----------+----------------+---------------+-------------+ INSERT INTO employees VALUES ('Lysandra','Reeves','1-212-759-3751','New York',10018), ('Michael','Arnett','1-650-230-8467','San Francisco',94116); SELECT * FROM employees; +------------+-----------+----------------+---------------+-------------+ | 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 | +------------+-----------+----------------+---------------+-------------+
在多行插入中,请确保插入值的数据类型在各行之间保持一致,因为第一行的数据类型将用作指南。以下操作将失败,因为第二行中值的数据类型与第一行中值的数据类型不同,即使这两个值都可以强制转换为 VARCHAR(即表中列的数据类型):
CREATE TABLE t1 (v VARCHAR); -- works as expected. INSERT INTO t1 (v) VALUES ('three'), ('four'); -- Fails with error "Numeric value 'd' is not recognized" -- even though the data type of 'd' is the same as the -- data type of the column v. INSERT INTO t1 (v) VALUES (3), ('d');
使用查询进行多行插入¶
将 contractors
表中的多行数据插入到 employees
表中:
仅选择
worknum
列中包含区号650
的行。在
city
列中插入 NULL 值。SELECT * FROM employees; +------------+-----------+----------------+---------------+-------------+ | 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 | +------------+-----------+----------------+---------------+-------------+ SELECT * FROM contractors; +------------------+-----------------+----------------+---------------+----------+ | 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; +------------+------------+----------------+---------------+-------------+ | 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;
使用源表中 id
列的 INNER JOIN 将两个表(emp_addr
、emp_ph
)中的列插入到第三个表 (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;
JSON 数据的多行插入¶
将两个 JSON 对象插入到表的 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, 7725" }') , ('{ "_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, 5922" }');
使用 Overwrite 插入¶
此示例使用带有 OVERWRITE 的 INSERT,在将新记录添加到 employees
表后,从 employees
重新构建 sf_employees
表。
下面是两个表的初始数据:
SELECT * FROM employees; +------------+-----------+----------------+---------------+-------------+ | 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; +------------+-----------+----------------+---------------+-------------+ | FIRST_NAME | LAST_NAME | WORKPHONE | CITY | POSTAL_CODE | |------------+-----------+----------------+---------------+-------------| | Martin | Short | 1-650-999-9999 | San Francisco | 94115 | +------------+-----------+----------------+---------------+-------------+
此语句使用 OVERWRITE 子句插入 sf_employees 表中:
INSERT OVERWRITE INTO sf_employees SELECT * FROM employees WHERE city = 'San Francisco';
由于 INSERT 使用了 OVERWRITE 选项,因此 sf_employees 的旧行不见了:
SELECT * FROM sf_employees; +------------+-----------+----------------+---------------+-------------+ | 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 | +------------+-----------+----------------+---------------+-------------+