Skip to content

PostgreSQL 插入数据

概述

INSERT 语句向 PostgreSQL 表添加新行。本章介绍插入数据的各种方式,包括单行、多行以及从其他表插入。

INSERT 语法

sql
INSERT INTO 表名 (列名) VALUES (值);
INSERT INTO 表名 DEFAULT VALUES;
INSERT INTO 表名 SELECT ...;

基本插入操作

插入单行

sql
-- 指定列名插入
INSERT INTO users (name, email, age) 
VALUES ('张三', 'zhangsan@example.com', 30);

-- 插入所有列(必须按顺序)
INSERT INTO users VALUES (1, '李四', 'lisi@example.com', 30, NOW());

-- 使用默认值
INSERT INTO users (name, email) VALUES ('王五', 'wangwu@example.com');

插入多行

sql
-- 单个INSERT语句插入多行
INSERT INTO products (name, price, category) VALUES 
    ('产品A', 19.99, '电子产品'),
    ('产品B', 29.99, '电子产品'),
    ('产品C', 39.99, '服装'),
    ('产品D', 49.99, '图书'),
    ('产品E', 59.99, '运动用品');

-- 可以高效插入数百行数据

使用SELECT语句插入

sql
-- 从其他表复制数据
INSERT INTO archive_users 
SELECT * FROM users WHERE deleted_at IS NOT NULL;

-- 插入特定列
INSERT INTO user_summary (user_id, name, email)
SELECT id, name, email FROM users WHERE status = 'active';

-- 带数据转换的插入
INSERT INTO daily_stats (stat_date, user_count)
SELECT CURRENT_DATE, COUNT(*) FROM users;

冲突处理

基本冲突处理

sql
-- 冲突时不做任何操作
INSERT INTO users (id, name, email) VALUES (1, '张三', 'zhangsan@example.com')
ON CONFLICT (id) DO NOTHING;

-- 冲突时更新数据
INSERT INTO users (id, name, email) VALUES (1, '张三更新', 'zhangsan.new@example.com')
ON CONFLICT (id) DO UPDATE SET 
    name = EXCLUDED.name,
    email = EXCLUDED.email,
    updated_at = NOW();

带条件的冲突处理

sql
-- 条件更新
INSERT INTO products (id, name, price) VALUES (1, '产品', 29.99)
ON CONFLICT (id) DO UPDATE SET 
    price = EXCLUDED.price
    WHERE products.stock > 0;

返回插入结果

sql
-- 返回插入的值
INSERT INTO users (name, email) VALUES ('新用户', 'new@example.com')
RETURNING id, name, created_at;

-- 返回所有列
INSERT INTO orders (user_id, total) VALUES (1, 99.99)
RETURNING *;

-- 返回特定表达式结果
INSERT INTO products (name, price) VALUES ('测试产品', 9.99)
RETURNING id, price * 1.1 AS 含税价格;

小结

PostgreSQL中的INSERT操作包括:

  • 基本插入、多行插入
  • 使用SELECT语句插入
  • 使用ON CONFLICT进行"upsert"操作
  • 使用RETURNING子句返回结果