在数据库开发过程中,我们经常需要在执行插入或更新操作后,立即获取对应的自增ID,用于后续的业务逻辑处理,比如关联其他表的数据、返回给前端作为唯一标识等。不同的关系型数据库提供了不同的原生语法来实现这个需求,其中RETURNING和OUTPUT是最常用的两种方式。

RETURNING 子句的使用
RETURNING子句主要用于PostgreSQL、Oracle、SQLite等数据库,它可以在INSERT、UPDATE、DELETE语句执行后,直接返回被操作行的指定字段值,不需要额外执行查询语句。
插入数据后返回自增ID
假设我们有一张用户表,其中id字段是自增主键,表结构如下:
-- PostgreSQL 建表语句
CREATE TABLE user_info (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL,
age INT
);
插入一条用户数据后,直接返回生成的id,SQL语句如下:
INSERT INTO user_info (username, age)
VALUES ('张三', 25)
RETURNING id;
执行上述语句后,会直接返回插入数据对应的自增id值,不需要再执行SELECT currval('user_info_id_seq')这样的查询语句。
更新数据后返回自增ID
如果需要更新某条数据,同时返回更新后的id(自增ID一般不会在更新时变化,这里只是演示语法),可以这样写:
UPDATE user_info SET age = 26 WHERE username = '张三' RETURNING id;
OUTPUT 子句的使用
OUTPUT子句是SQL Server提供的语法,功能与RETURNING类似,可以在数据操作语句执行后返回受影响行的字段值。
插入数据后返回自增ID
首先创建对应的用户表,SQL Server的自增字段使用IDENTITY关键字定义:
-- SQL Server 建表语句
CREATE TABLE user_info (
id INT IDENTITY(1,1) PRIMARY KEY,
username VARCHAR(50) NOT NULL,
age INT
);
插入数据后返回自增id的语句如下:
INSERT INTO user_info (username, age)
OUTPUT INSERTED.id
VALUES ('李四', 30);
这里的INSERTED是SQL Server的临时表,存储了刚刚插入的行数据,通过INSERTED.id就可以获取到对应的自增ID。如果是更新操作,还可以使用DELETED临时表获取更新前的数据,UPDATED临时表获取更新后的数据。
更新数据后返回自增ID
更新数据时返回id的示例如下:
UPDATE user_info SET age = 31 OUTPUT INSERTED.id WHERE username = '李四';
两种语法的注意事项
- RETURNING子句在不同数据库中的支持程度不同,MySQL目前不支持该语法,如果需要获取插入后的自增ID,可以使用LAST_INSERT_ID()函数。
- 使用OUTPUT子句时,如果插入或更新的行数较多,返回的结果集也会比较大,需要根据实际业务场景判断是否需要返回所有行的ID。
- 在事务中使用这两种语法时,返回的值只有在事务提交后才会正式生效,回滚事务后对应的ID不会实际生成。
代码示例:在程序中获取返回的自增ID
以Python操作PostgreSQL为例,演示如何获取RETURNING返回的自增ID:
import psycopg2
# 连接数据库
conn = psycopg2.connect(
dbname="test_db",
user="postgres",
password="123456",
host="127.0.0.1",
port="5432"
)
cursor = conn.cursor()
# 执行插入语句并获取返回的id
cursor.execute("INSERT INTO user_info (username, age) VALUES ('王五', 28) RETURNING id")
new_id = cursor.fetchone()[0]
conn.commit()
print(f"新插入的用户ID是:{new_id}")
cursor.close()
conn.close()
如果是操作SQL Server,使用pymssql库的示例代码如下:
import pymssql
# 连接数据库
conn = pymssql.connect(
server="127.0.0.1",
user="sa",
password="123456",
database="test_db"
)
cursor = conn.cursor()
# 执行插入语句并获取返回的id
cursor.execute("INSERT INTO user_info (username, age) OUTPUT INSERTED.id VALUES ('赵六', 35)")
new_id = cursor.fetchone()[0]
conn.commit()
print(f"新插入的用户ID是:{new_id}")
cursor.close()
conn.close()