INSERT

Name

INSERT -- 在一个表中创建新行

Synopsis

[ WITH [ RECURSIVE ] with_query [, ...] ]
INSERT INTO table_name [ ( column_name [, ...] ) ]
    { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

描述

INSERT将新行插入到一个表中。我们可以 插入一个或者更多由值表达式指定的行,或者插入来自一个查询的零行 或者更多行。

目标列的名称可以以任意顺序列出。如果没有给出列名列表,则有两种确定 目标列的可能性。第一种是以被声明的顺序列出该表的所有列。另一种可能 性是,如果VALUES 子句或者query只提 供N个列,则以被声明的顺序列出该表的前 N列。VALUES 子句或者 query提供的值会被从左至右关联到这些显式或者隐式 给出的目标列。

每一个没有出现在显式或者隐式列列表中的列都将被默认填充,如果为该列 声明过默认值则用默认值填充,否则用空值填充。

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

可选的RETURNING子句会让INSERT根据 实际被插入的每一行计算并且返回值。这主要用于获得默认提供的值,例如 序列号。不过,允许在其中有使用该表列的任何表达式。 RETURNING列表的语法和SELECT的输出 列表相同。

为了向表中插入,必须拥有其上的INSERT特权。如果 指定了列列表,只需要列出的列上的INSERT特权。使用 RETURNING子句要求RETURNING中提到的所 有列上的SELECT特权。如果使用query子句插入来自于一个查询的行, 当然需要具有该查询中用到的任何表或者列上的SELECT特权。

参数

with_query

WITH子句允许指定一个或者更多子查询,在 INSERT查询中可以用名称引用这些子查询。详见 Section 7.8以及SELECT

querySELECT语句)也可以包含一个 WITH子句。在这种情况下 query中可以引用 两组with_query,但是第二个优先级更 高(因为它被嵌套更近)。

table_name

一个已有表的名称(可以被模式限定)。

column_name

table_name中 表的一个列的名称。如果需要,可以在列名后加上一个子域名或者数组 下标进行限定(只向一个组合列的某些域插入会让其他域变成空值)。

DEFAULT VALUES

所有列都将被其默认值填充。

expression

要赋予给相应列的表达式或者值。

DEFAULT

相应的列将被其默认值填充。

query

提供要被插入行的查询(SELECT语句)。 其语法描述请参考SELECT语句。

output_expression

在每一行被插入后由INSERT命令计算并且返回的 表达式。该表达式可以使用table_name 指定的表中的任何列。写成*可返回被插入行的所有列。

output_name

要用于被返回列的名称。

输出

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

INSERT oid count

count是被插入的行数。 如果count正好为 1 并且 目标表具有 OID,那么 oid就是分配给被插入行的 OID。否则 oid为零。

如果INSERT命令包含RETURNING子句, 其结果会类似于包含RETURNING列表中定义的列和值的 SELECT语句,这些结果是由该命令在被插入行上计算 得到。

示例

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;

用多行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中获得一些行插入到表 films中,两个表具有相同的列布局:

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

这个例子插入数组列:

-- 为 noughts-and-crosses 游戏创建一个空的 3x3 棋盘
INSERT INTO tictactoe (game, board[1:3][1:3])
    VALUES (1, '{{" "," "," "},{" "," "," "},{" "," "," "}}');
-- 实际上可以不用上面例子中的下标
INSERT INTO tictactoe (game, board)
    VALUES (2, '{{X," "," "},{" ",O," "},{" ",X," "}}');

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

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

增加为 Acme 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;

兼容性

INSERT符合 SQL 标准,不过 RETURNING子句是一种 PostgreSQL扩展, 在 INSERT中使用WITH也是。 还有,标准不允许省略列名列表但不通过 VALUES子句或者query填充 所有列的情况。

query子句可能的限制在 SELECT有介绍。