PostgreSQL中推荐使用RETURNING子句在INSERT后直接获取主键,因其确保原子性、避免竞态条件,并减少数据库往返。该方法适用于SERIAL、UUID等主键类型,且可与ON CONFLICT结合实现UPSERT并返回更新后的记录信息,提升效率与代码简洁性。

在PostgreSQL中,如果你想在执行
INSERT
RETURNING id
在PostgreSQL中,当你需要在一个
INSERT
RETURNING
想象一下,你有一个
users
id
SERIAL
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE
);当你插入一条新用户记录时,你只需要在
INSERT
RETURNING id
INSERT INTO users (username, email) VALUES ('alice', 'alice@example.com') RETURNING id;执行这条语句后,PostgreSQL会直接返回一个结果集,其中包含新插入记录的
id
INSERT INTO users (username, email) VALUES
('bob', 'bob@example.com'),
('charlie', 'charlie@example.com')
RETURNING id, username;它会返回一个包含两行记录的结果集,每行包含对应的
id
username
id
RETURNING
我个人觉得,
RETURNING
最核心的一点是原子性。在没有
RETURNING
INSERT
SELECT
SELECT id FROM users WHERE username = 'alice' AND email = 'alice@example.com'
INSERT
SELECT
username
RETURNING
其次,它极大地简化了应用层的代码逻辑。开发者不需要编写额外的查询语句,也不需要担心如何精确地匹配到刚刚插入的那条记录。一个简单的
INSERT ... RETURNING id
最后,是性能上的优势。将
INSERT
SELECT
SERIAL
RETURNING
当然可以!
RETURNING
SERIAL
BIGSERIAL
UUID
INSERT
RETURNING
举个例子,如果你的主键是一个
UUID
CREATE TABLE products (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 或者在应用层生成
    name VARCHAR(100) NOT NULL,
    price NUMERIC(10, 2)
);假设你让数据库自动生成UUID:
INSERT INTO products (name, price) VALUES ('Laptop', 1200.00) RETURNING id;或者,如果你在应用层生成了UUID:
-- 假设应用层生成了 'a1b2c3d4-e5f6-7890-1234-567890abcdef'
INSERT INTO products (id, name, price) VALUES ('a1b2c3d4-e5f6-7890-1234-567890abcdef', 'Monitor', 300.00) RETURNING id;在这两种情况下,
RETURNING id
UUID
甚至,你不仅仅可以返回主键,任何你认为在
INSERT
RETURNING
order_id
created_at
CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    customer_id INT NOT NULL,
    order_date TIMESTAMP DEFAULT NOW()
);
INSERT INTO orders (customer_id) VALUES (101) RETURNING order_id, order_date;这会返回新订单的ID和数据库自动生成的创建时间。这种灵活性使得
RETURNING
ON CONFLICT
RETURNING
这里要提到一个PostgreSQL的杀手级特性——
INSERT ... ON CONFLICT
RETURNING
想象一个场景:你需要插入一条记录,但如果这条记录(根据某个唯一约束)已经存在,你就想更新它,并且无论最终是插入还是更新,你都希望获取到最终那条记录的ID和一些其他信息。这就是
INSERT ... ON CONFLICT ... DO UPDATE ... RETURNING
我们继续用
users
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE
);现在,我们想插入一个用户,如果
username
-- 第一次插入,'john@example.com' 不存在
INSERT INTO users (username, email) VALUES ('John Doe', 'john@example.com')
ON CONFLICT (email) DO UPDATE SET username = EXCLUDED.username
RETURNING id, username, email;
-- 假设返回 id=1, username='John Doe', email='john@example.com'
-- 第二次插入,'john@example.com' 已经存在,会触发更新
INSERT INTO users (username, email) VALUES ('Johnny Bravo', 'john@example.com')
ON CONFLICT (email) DO UPDATE SET username = EXCLUDED.username
RETURNING id, username, email;在第二次执行时,由于
ON CONFLICT
username
Johnny Bravo
RETURNING
id=1
username='Johnny Bravo'
email='john@example.com'
这个机制非常强大,它让你的应用程序可以以一种统一的方式处理“插入或更新并获取结果”的逻辑,无论是新增还是修改,你都能拿到最新、最准确的数据状态。这大大简化了业务逻辑层面的判断和处理,避免了多次查询和复杂的事务控制,让代码更健壮、更高效。在我看来,这是PostgreSQL在处理数据同步和数据一致性方面的一个非常优雅的解决方案。
以上就是PostgreSQL插入返回ID怎么实现_PostgreSQL插入返回主键方法的详细内容,更多请关注php中文网其它相关文章!
 
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
 
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号