Tip

INSERT

INSERT —在表中创建新行

Synopsis

[ WITH [ RECURSIVE ] with_query [, ...] ]
INSERT INTO table_name [ AS alias ] [ ( column_name [, ...] ) ]
    [ OVERRIDING { SYSTEM | USER } VALUE ]
    { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
    [ ON CONFLICT [ conflict_target ] conflict_action ]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

where conflict_target can be one of:

    ( { index_column_name | ( index_expression ) } [ COLLATE collation ] [ opclass ] [, ...] ) [ WHERE index_predicate ]
    ON CONSTRAINT constraint_name

and conflict_action is one of:

    DO NOTHING
    DO UPDATE SET { column_name = { expression | DEFAULT } |
                    ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |
                    ( column_name [, ...] ) = ( sub-SELECT )
                  } [, ...]
              [ WHERE condition ]

Description

INSERT将新行插入表中。可以插入由值表达式指定的一或多个行,或查询产生的零或多个行。

目标列名称可以按任何 Sequences 列出。如果根本没有给出任何列名列表,则默认值为表中所有列的声明 Sequences;否则为默认值。如果VALUES子句或* query 仅提供 N 列,则返回第一个 N 列名。 VALUES子句或 query *提供的值与从左到右的显式或隐式列列表相关联。

显式或隐式列列表中不存在的每个列都将填充一个默认值,或者是其声明的默认值,如果没有,则为 null。

如果任何列的表达式的数据类型都不正确,则将尝试自动类型转换。

ON CONFLICT可用于指定引发唯一约束或排除约束违反错误的替代操作。 (请参见下面的冲突条款。)

可选的RETURNING子句使INSERT根据实际插入(或使用ON CONFLICT DO UPDATE子句更新)的每一行计算并返回值。这对于获取默认提供的值(例如序列号)非常有用。但是,允许使用表列的任何表达式。 RETURNING列表的语法与SELECT的输出列表的语法相同。仅返回成功插入或更新的行。例如,如果由于不满足ON CONFLICT DO UPDATE ... WHERE子句* condition *而导致某行被锁定但未更新,则不会返回该行。

您必须对表具有INSERT特权才能插入表中。如果存在ON CONFLICT DO UPDATE,则还需要对表具有UPDATE特权。

如果指定了列列表,则只需要对列出的列具有INSERT特权。同样,指定ON CONFLICT DO UPDATE时,您只需要对列出的要更新的列具有UPDATE特权。但是,ON CONFLICT DO UPDATE还要求对在ON CONFLICT DO UPDATE表达式或* condition *中读取其值的任何列具有SELECT特权。

使用RETURNING子句需要RETURNING中提到的所有列具有SELECT特权。如果使用* query *子句从查询中插入行,那么您当然需要对查询中使用的任何表或列具有SELECT特权。

Parameters

Inserting

本节介绍仅插入新行时可以使用的参数。 ON CONFLICT子句“专有地”使用的参数将单独描述。

例如,在表之间复制值时,此子句很有用。写入INSERT INTO tbl2 OVERRIDING USER VALUE SELECT * FROM tbl1将从tbl1复制tbl2中不是身份列的所有列,而tbl2中的身份列的值将由与tbl2关联的序列生成。

ON CONFLICT 条款

可选的ON CONFLICT子句指定引发唯一违反或排除约束违反错误的替代操作。对于建议插入的每个单独行,要么 continue 插入,要么如果违反了* conflict_target 指定的 arbiter 约束或索引,则采用替代项 conflict_action *。 ON CONFLICT DO NOTHING只是避免插入行作为其替代操作。 ON CONFLICT DO UPDATE更新与建议作为插入操作插入的行冲突的现有行。

ON CONFLICT DO UPDATE确保原子INSERTUPDATE的结果;如果没有独立的错误,即使在高并发情况下,也可以保证这两个结果之一。这也称为* UPSERT *-“更新或插入”。

请注意,所有每行BEFORE INSERT触发器的效果都反映在excluded值中,因为这些效果可能导致该行被排除在插入之外。

请注意,不支持将排除约束作为ON CONFLICT DO UPDATE的仲裁器。在所有情况下,仅支持NOT DEFERRABLE约束和唯一索引作为仲裁器。

带有ON CONFLICT DO UPDATE子句的INSERT是“确定性”语句。这意味着该命令不允许多次影响任何单个现有行;发生这种情况时,将引发基数违反错误。建议插入的行不应在受仲裁器索引或约束约束的属性方面相互重复。

请注意,当前不支持将INSERTON CONFLICT DO UPDATE子句应用于已分区表以更新冲突行的分区键,从而要求将该行移至新分区。

Tip

通常最好使用唯一索引推断,而不是直接使用ON CONFLICT ON CONSTRAINT * constraint_name *命名约束。当基础索引被另一个或多或少等效的索引以重叠方式替换时,例如在删除要替换的索引之前使用CREATE UNIQUE INDEX ... CONCURRENTLY时,推理将 continue 正常工作。

Outputs

成功完成后,INSERT命令将返回以下形式的命令标签:

INSERT oid count

如果INSERT命令包含RETURNING子句,则结果将类似于SELECT语句的结果,该语句包含在RETURNING列表中定义的列和值,并通过该命令插入或更新的行进行计算。

Notes

如果指定的表是分区表,则将每一行路由到适当的分区并插入其中。如果指定的表是分区,则如果 Importing 行之一违反分区约束,则会发生错误。

Examples

在表films中插入一行:

INSERT INTO films VALUES
    ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes');

在此示例中,省略了len列,因此它将具有默认值:

INSERT INTO films (code, title, did, date_prod, kind)
    VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama');

本示例对日期列使用DEFAULT子句,而不是指定值:

INSERT INTO films VALUES
    ('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes');
INSERT INTO films (code, title, did, date_prod, kind)
    VALUES ('T_601', 'Yojimbo', 106, DEFAULT, 'Drama');

要插入完全由默认值组成的行:

INSERT INTO films DEFAULT VALUES;

要使用 multirow VALUES语法插入多行:

INSERT INTO films (code, title, did, date_prod, kind) VALUES
    ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
    ('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');

本示例将表tmp_films中的某些行从表tmp_films插入到表films中,其列布局与films相同:

INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';

本示例将插入数组列:

-- Create an empty 3x3 gameboard for noughts-and-crosses
INSERT INTO tictactoe (game, board[1:3][1:3])
    VALUES (1, '{{" "," "," "},{" "," "," "},{" "," "," "}}');
-- The subscripts in the above example aren't really needed
INSERT INTO tictactoe (game, board)
    VALUES (2, '{{X," "," "},{" ",O," "},{" ",X," "}}');

在表distributors中插入一行,返回DEFAULT子句生成的序列号:

INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets')
   RETURNING did;

增加 ManagementAcme Corporation 帐户的销售人员的销售数量,并在日志表中记录整个更新的行以及当前时间:

WITH upd AS (
  UPDATE employees SET sales_count = sales_count + 1 WHERE id =
    (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation')
    RETURNING *
)
INSERT INTO employees_log SELECT *, current_timestamp FROM upd;

插入或更新适当的新发行商。假定已经定义了唯一索引,该唯一索引限制了出现在did列中的值。请注意,特殊的excluded表用于引用最初建议用于插入的值:

INSERT INTO distributors (did, dname)
    VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc')
    ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname;

插入分配器,或者在存在现有的排除行(具有匹配约束列的行或行插入触发触发后的列)时,对建议插入的行不执行任何操作。该示例假定已定义一个唯一索引来约束出现在did列中的值:

INSERT INTO distributors (did, dname) VALUES (7, 'Redline GmbH')
    ON CONFLICT (did) DO NOTHING;

插入或更新适当的新发行商。该示例假定已定义了唯一索引,该唯一索引约束了出现在did列中的值。 WHERE子句用于限制实际更新的行(但是,任何未更新的现有行仍将被锁定):

-- Don't update existing distributors based in a certain ZIP code
INSERT INTO distributors AS d (did, dname) VALUES (8, 'Anvil Distribution')
    ON CONFLICT (did) DO UPDATE
    SET dname = EXCLUDED.dname || ' (formerly ' || d.dname || ')'
    WHERE d.zipcode <> '21201';

-- Name a constraint directly in the statement (uses associated
-- index to arbitrate taking the DO NOTHING action)
INSERT INTO distributors (did, dname) VALUES (9, 'Antwerp Design')
    ON CONFLICT ON CONSTRAINT distributors_pkey DO NOTHING;

尽可能插入新的分配器;否则为DO NOTHING。该示例假定已定义一个唯一索引,该索引将约束出现在is_active布尔列求值为true的行的子集上did列中的值:

-- This statement could infer a partial unique index on "did"
-- with a predicate of "WHERE is_active", but it could also
-- just use a regular unique constraint on "did"
INSERT INTO distributors (did, dname) VALUES (10, 'Conrad International')
    ON CONFLICT (did) WHERE is_active DO NOTHING;

Compatibility

INSERT符合 SQL 标准,但RETURNING子句是 PostgreSQL 扩展,使用WITHINSERT的能力以及使用ON CONFLICT指定替代动作的能力。此外,标准不允许列名列表被省略,但不是所有列都由VALUES子句或* query *填充的情况。

SQL 标准指定只有在始终生成的标识列存在的情况下才能指定OVERRIDING SYSTEM VALUE。 PostgreSQL 在任何情况下都允许该子句,如果不适用则将其忽略。

上一章 首页 下一章