INSERT
将值插入指定表的所有投影。每次只能插入一个完整的元组。如果没有与目标表关联的投影,Vertica 会创建一个超投影以存储插入值。
INSERT 适用于 flex 表以及常规原生表。如果表包含实际列,则会将标量类型的插入数据和标量类型的原生数组添加到实际列和 __raw__
列。对于复杂类型的数据,不会将值添加到 __raw__
列。
语法
INSERT [ /*+LABEL (label‑string)*/ ] INTO [[database.]schema.]table-name
[ ( column-list ) ]
{ DEFAULT VALUES | VALUES ( values-list )[,...] | SELECT {{< codevar >}}query-expression{{< /codevar >}} }
参数
-
LABEL
将标签分配到语句,以便您可以在分析和调试时识别它。
-
[database.]schema
数据库和架构。默认架构为
public
。如果指定一个数据库,它必须是当前数据库。-
table‑name
- 目标表。不能在投影中调用 INSERT。
-
column‑list
- 此表中一个或多个目标列的逗号分隔列表,按任意顺序列出。VALUES 子句值将以相同的顺序映射到列。如果忽略此列表,Vertica 将根据表定义中的列顺序将 VALUES 子句值映射到列。
DEFAULT VALUES 对目标列列表无效。
DEFAULT VALUES
- 使用表定义中指定的默认值填充所有列。如果没有为列指定默认值,Vertica 将插入 NULL 值。
不能使用此选项指定目标列的列表。
-
VALUES (values‑list)
- 要在目标列中插入的一个或多个值的逗号分隔列表,其中每个值是以下值之一:
-
expression 将解析为要插入到目标列中的值。表达式不得嵌套其他表达式(包含 Vertica 元函数)或使用混合复杂类型。如果 Vertica 可以强制转换元素或字段类型,则值可能包括原生数组或 ROW 类型。
-
DEFAULT 将插入表定义中指定的默认值。
如果没有为列提供值,Vertica 会隐式添加 DEFAULT 值(如果已定义)。否则,Vertica 将插入 NULL 值。如果将列定义为 NOT NULL,则 INSERT 将返回错误。
您可以使用 INSERT 在目标表中插入多行,方法是指定多个以逗号分隔的 VALUES 列表:
INSERT INTO table-name VALUES ( values-list ), ( values-list )[,...]
有关详细信息,请参阅下面的多行 INSERT。
-
-
SELECT query‑expression
- 返回要插入的行的查询。隔离级别仅适用于 SELECT 子句并且按照任意查询的方式工作。对使用复杂类型的限制同样适用于其他查询。
特权
-
表所有者或具有 GRANT OPTION 权限的用户是授予者
-
对表的 INSERT 权限
-
包含表的架构上的 USAGE 权限
Vertica 采用 SQL-92 事务模型,因此连续的 INSERT、UPDATE 和 DELETE 语句包含在同一个事务中。您无需显式启动此事务,但必须使用 COMMIT 显式结束它,或者使用 COPY 隐式结束它。否则,Vertica 将放弃在该事务中所做的所有更改。
多行 INSERT
通过指定多个以逗号分隔的 VALUES 列表,您可以使用 INSERT 在目标表中插入多行。例如:
=> CREATE TABLE public.t1(a int, b int, c varchar(16));
CREATE TABLE
=> INSERT INTO t1 VALUES (1,2, 'un, deux'), (3,4, 'trois, quatre');
OUTPUT
--------
2
(1 row)
=> COMMIT;
COMMIT
=> SELECT * FROM t1;
a | b | c
---+---+---------------
1 | 2 | un, deux
3 | 4 | trois, quatre
(4 rows)
限制
-
Vertica 不支持将子查询作为 INSERT 语句的目标。
-
对在 SELECT 语句中使用 复杂类型的限制同样适用于 INSERT。使用无法强制转换为列类型的复杂值会导致错误。
-
如果在目标表中启用了主键、唯一键或检查约束以自动强制实施,Vertica 会在您加载新数据时强制实施这些约束。如果发生违规,Vertica 会回滚操作并返回错误。
-
如果插入会违反表或架构磁盘配额,则操作将失败。有关详细信息,请参阅磁盘配额。
示例
=> INSERT INTO t1 VALUES (101, 102, 103, 104);
=> INSERT INTO customer VALUES (10, 'male', 'DPR', 'MA', 35);
=> INSERT INTO start_time VALUES (12, 'film','05:10:00:01');
=> INSERT INTO retail.t1 (C0, C1) VALUES (1, 1001);
=> INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';
Vertica 不支持将子查询或嵌套的表达式作为 INSERT 语句的目标。例如,以下查询会返回一条错误消息:
=> INSERT INTO t1 (col1, col2) VALUES ('abc', (SELECT mycolumn FROM mytable));
ERROR 4821: Subqueries not allowed in target of insert
您可以重新编写以上查询,如下所示:
=> INSERT INTO t1 (col1, col2) (SELECT 'abc', mycolumn FROM mytable);
OUTPUT
--------
0
(1 row)
以下示例显示了如何将 INSERT...VALUES 与 flex 表一起使用:
=> CREATE FLEX TABLE flex1();
CREATE TABLE
=> INSERT INTO flex1(a,b) VALUES (1, 'x');
OUTPUT
--------
1
(1 row)
=> SELECT MapToString(__raw__) FROM flex1;
MapToString
---------------------------------
{
"a" : "1",
"b" : "x"
}
(1 row)
以下示例显示了如何将 INSERT...SELECT 与 flex 表一起使用:
=> CREATE FLEX TABLE flex2();
CREATE TABLE
=> INSERT INTO flex2(a, b) SELECT a, b, '2016-08-10 11:10' c, 'Hello' d, 3.1415 e, f from flex1;
OUTPUT
--------
1
(1 row)
=> SELECT MapToString(__raw__) FROM flex2;
MapToString
---------------------------------
{
"a" : "1",
"b" : "x",
"c" : "2016-08-10",
"d" : "Hello",
"e" : 3.1415,
"f" : null
}
(1 row)
以下示例使用复杂类型:
=> CREATE TABLE inventory(storeID INT, product ROW(name VARCHAR, code VARCHAR));
CREATE TABLE
--- LookUpProducts() returns a row(varchar, int), which is cast to row(varchar, varchar):
=> INSERT INTO inventory(product) SELECT LookUpProducts();
OUTPUT
--------
5
(1 row)
--- Cannot use with select...values:
=> INSERT INTO inventory(product) VALUES(LookUpProducts());
ERROR 2631: Column "product" is of type "row(varchar,varchar)" but expression is of type "row(varchar,int)"
--- Literal values are supported:
=> INSERT INTO inventory(product) VALUES(ROW('xbox',165));
OUTPUT
--------
1
(1 row)
=> SELECT product FROM inventory;
product
------------------------------
{"name":"xbox","code":"125"}
(1 row)