SESSION_USER返回会话建立时认证的原始用户名,不随SET ROLE等权限切换改变;PostgreSQL中它恒等于初始登录用户,SQL Server中对应登录名,MySQL则不支持该函数。

SESSION_USER 返回的是登录用户,不是执行用户
在 PostgreSQL 和 SQL Server 中,SESSION_USER 返回的是当前会话建立时认证的用户名,和 CURRENT_USER 不同——后者可能因权限切换(如 SET ROLE)而变化。如果你用 psql -U alice 连接,即使后续执行 SET ROLE bob,SESSION_USER 仍返回 alice。
- PostgreSQL 中它等价于
USER和CURRENT_USER的初始值,但不随SET ROLE改变 - SQL Server 中它始终对应登录名(Login),而非数据库用户(User)
- MySQL 不支持
SESSION_USER,应改用USER()或CURRENT_USER(),二者行为也不同:USER()是“客户端声明的用户名@主机”,CURRENT_USER()是服务器实际匹配的授权账户
在 SELECT、WHERE 和函数参数中直接调用
SESSION_USER 是一个无参标量函数,可直接出现在表达式里,不需要括号(PostgreSQL 允许带空括号,但不推荐;SQL Server 必须不带括号)。
- 在查询中获取当前会话用户:
SELECT SESSION_USER AS current_session_user; - 用于审计日志字段默认值:
INSERT INTO audit_log (action, user_id) VALUES ('DELETE', SESSION_USER); - 在 WHERE 中做权限粗筛(注意:不能替代行级安全策略):
SELECT * FROM orders WHERE owner = SESSION_USER; - 在存储过程或函数内作为默认参数值(PostgreSQL):
CREATE FUNCTION log_action(action TEXT, usr TEXT DEFAULT SESSION_USER) ...
常见错误:混淆 SESSION_USER 和 CURRENT_USER
最常踩的坑是误以为 SESSION_USER 会随 SET ROLE 或 SET SESSION AUTHORIZATION 动态更新。它不会。例如:
SET ROLE 'admin';<br>SELECT SESSION_USER, CURRENT_USER;
结果中 SESSION_USER 仍是原始登录用户,CURRENT_USER 才是 admin。若业务逻辑依赖“当前有效角色”,必须用 CURRENT_USER 或 CURRENT_ROLE。
- PostgreSQL 中
CURRENT_USER可被SET ROLE修改,SESSION_USER不可 - SQL Server 中没有
CURRENT_USER对应物,SESSION_USER就是登录名,要查当前数据库用户需用USER_NAME() - Oracle 使用
USER(等价于SESSION_USER),但无标准CURRENT_USER;其SESSION_USER是保留字,实际用USER
跨数据库兼容性差,别硬写通用 SQL
想写一套 SQL 在 PostgreSQL、SQL Server、MySQL 都跑通?SESSION_USER 基本做不到。各系统对“当前用户”的定义和函数名差异太大:
- PostgreSQL:
SESSION_USER、CURRENT_USER、USER都可用,语义有区别 - SQL Server:
SESSION_USER存在,但更常用SUSER_NAME()(Windows 登录)或USER_NAME()(数据库用户) - MySQL:
SESSION_USER()不存在,USER()和CURRENT_USER()行为不同,且返回格式含主机部分(如'alice@localhost') - SQLite:无内置会话用户函数,需靠应用层传入
真正需要跨库时,要么在应用层统一注入用户标识,要么封装成数据库特定视图或函数,避免 SQL 层硬编码 SESSION_USER。


















