[ 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子句允许指定一个或者更多子查询,在 INSERT查询中可以用名称引用这些子查询。详见 Section 7.8以及SELECT。
query (SELECT语句)也可以包含一个 WITH子句。在这种情况下 query中可以引用 两组with_query,但是第二个优先级更 高(因为它被嵌套更近)。
一个已有表的名称(可以被模式限定)。
table_name中 表的一个列的名称。如果需要,可以在列名后加上一个子域名或者数组 下标进行限定(只向一个组合列的某些域插入会让其他域变成空值)。
所有列都将被其默认值填充。
要赋予给相应列的表达式或者值。
相应的列将被其默认值填充。
提供要被插入行的查询(SELECT语句)。 其语法描述请参考SELECT语句。
在每一行被插入后由INSERT命令计算并且返回的 表达式。该表达式可以使用table_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有介绍。