MySQL查当前用户能访问的所有表,应使用SHOW TABLES(最快,仅当前库普通表)或SELECT查询INFORMATION_SCHEMA.TABLES(可区分表/视图、受权限静默过滤)。

MySQL怎么查当前用户能访问的所有表
MySQL里没有“当前用户下所有表”的绝对概念,因为表属于数据库(schema),不是用户。真正要查的是:当前用户有权限访问的、在指定数据库里的所有表。最常用的是查当前默认数据库下的表,用 SHOW TABLES 最直接:
它不依赖权限视图,只要对当前数据库有 SELECT 或 SHOW VIEW 权限就能执行
如果需要跨库或更精确控制权限范围,就得查系统表 information_schema.tables:
SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE';
注意:DATABASE() 返回当前默认数据库名;如果没选库,DATABASE() 是 NULL,查不出结果——得显式指定 table_schema = 'your_db_name'
常见踩坑:
-
information_schema.tables对所有用户可见,但只会返回当前用户有权限查看的表,这点很关键 - 用
TABLE_SCHEMA而不是OWNER字段,MySQL 没有 owner 概念 - 想包含视图,把
table_type = 'BASE TABLE'改成IN ('BASE TABLE', 'VIEW')
PostgreSQL如何列出当前用户可查的所有表
PostgreSQL 表归属更明确:每个表属于一个 schema,而 schema 可以由用户拥有。但“当前用户下的表”仍需拆解为“当前用户有 USAGE 权限的 schema 中、该用户有 SELECT 权限的表”。最稳妥是查 pg_tables 视图:
SELECT schemaname, tablename
FROM pg_tables
WHERE schemaname NOT IN ('pg_catalog', 'information_schema');
这个查询默认只显示当前用户有权限访问的表(pg_tables 本身做了权限过滤)
如果想严格限定“当前用户所拥有”的表(即 tableowner = CURRENT_USER),得关联 pg_class 和 pg_namespace:
SELECT n.nspname AS schemaname, c.relname AS tablename
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
AND n.nspname NOT IN ('pg_catalog', 'information_schema')
AND c.relowner = (SELECT oid FROM pg_roles WHERE rolname = CURRENT_USER);
注意点:
-
pg_tables是视图,已过滤掉无权限的 schema;但如果你GRANT USAGE ON SCHEMA xxx TO user却没给表级权限,它也不会出现 -
relkind = 'r'表示普通表,'v'是视图,'m'是物化视图 - 别漏掉
nspname过滤,否则pg_catalog里的系统表会混进来
Oracle中查当前用户有权限访问的表有哪些
Oracle 分两类场景:查自己创建的表(USER_TABLES),或查所有自己能访问的表(ALL_TABLES)。绝大多数情况应该用后者:
SELECT owner, table_name
FROM ALL_TABLES
WHERE owner NOT IN ('SYS', 'SYSTEM', 'ORDSYS');
ALL_TABLES 自动只返回当前用户被授予了 SELECT 权限的表,包括别人授权给你的
如果只想看自己创建的(且未被 DROP 的),用 USER_TABLES:
SELECT table_name FROM USER_TABLES;
关键区别:
-
USER_*视图只显示当前用户的对象,不检查权限,只看属主 -
ALL_*视图才体现“可访问性”,是真实权限边界 -
DBA_*需要 DBA 权限,普通用户查不到 - Oracle 的
owner字段就是创建者用户名,和 PostgreSQL 的relowner类似但语义更重
SQL Server怎么获取当前登录用户能查的表列表
SQL Server 没有统一的“当前用户下所有表”视图,得组合权限检查。最实用的是查 sys.tables 并用 HAS_PERMS_BY_NAME 过滤:
SELECT s.name AS schema_name, t.name AS table_name
FROM sys.tables t
JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE HAS_PERMS_BY_NAME(QUOTENAME(s.name) + '.' + QUOTENAME(t.name), 'OBJECT', 'SELECT') = 1;
这个写法可靠,但性能略低(每行调一次权限函数),适合交互查询,不适合高频调用
更轻量的方式是查 sys.database_permissions 关联 sys.database_principals,但逻辑复杂,容易漏掉 public 权限或角色继承
注意事项:
- 不要用
sys.objects直接筛type = 'U',它不校验权限 -
QUOTENAME()必须加,防止 schema 或表名含空格或特殊字符导致语法错误 - 如果用户是 db_owner 角色成员,上面的
HAS_PERMS_BY_NAME查询会返回所有用户表——这是预期行为

















