如何在Snowflake中对SHOW <object>类DDL结果执行子查询
报错根本原因
Snowflake 所有SHOW <object>系列语句(包含SHOW GRANTS TO ROLE)的返回结果是面向客户端直接渲染的会话级临时结果,原生不支持直接作为子查询、关联查询的数据源,直接嵌套SHOW语句写子查询触发报错是语法层面的设计限制,不是操作失误。
可落地的实现方案
- 方案1:用
RESULT_SCAN函数承接SHOW结果(实时性最高,适合临时查询)
必须在同一会话内、SHOW语句执行后立刻调用,通过LAST_QUERY_ID()拿到上一条SHOW语句的结果ID即可做任意后续查询,示例:-- 先执行目标SHOW语句 SHOW GRANTS TO ROLE SYSADMIN; -- 承接结果做过滤、聚合等操作,注意返回列名默认大写,需要加双引号引用 SELECT "privilege", "granted_on", "name" AS object_name FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) WHERE "granted_on" = 'TABLE'; - 方案2:直接查询系统内置权限视图(最灵活,适合固化到脚本/任务)
不需要依赖会话上下文,直接查询账号级系统视图即可拿到角色授权数据,支持任意子查询、关联操作,没有两步执行的限制:
注意这个视图的数据有最长15分钟的同步延迟,对实时性要求极高的场景选方案1;查询需要对应ACCOUNT_USAGE schema的访问权限,默认ACCOUNTADMIN角色持有该权限。SELECT PRIVILEGE, GRANTED_ON, NAME AS object_name FROM SNOWFLAKE.ACCOUNT_USAGE.GRANTS_TO_ROLES WHERE ROLE = 'SYSADMIN' AND DELETED_ON IS NULL; -- 过滤掉已经回收的历史权限 - 方案3:结果持久化到临时表(适合多次复用结果的场景)
如果需要多次引用SHOW返回的权限数据,可以把结果写入临时表,后续直接查表即可,不需要重复执行SHOW语句:SHOW GRANTS TO ROLE SYSADMIN; CREATE OR REPLACE TEMP TABLE tmp_sysadmin_grants AS SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())); -- 后续任意查询直接读临时表 SELECT * FROM tmp_sysadmin_grants WHERE "privilege" = 'OWNERSHIP';
常见报错排查
- 报
invalid identifier错误:查询RESULT_SCAN返回结果时,列名没有加双引号匹配默认的全大写列名,或者列名拼写错误,可以先单独执行SHOW语句确认返回列名后再写查询逻辑。 - 报
result scan not found错误:要么是跨会话调用了RESULT_SCAN,要么是SHOW语句执行后又运行了其他SQL,导致LAST_QUERY_ID()指向的不是SHOW语句的结果,可以手动指定SHOW语句的查询ID传入RESULT_SCAN解决。 - 查ACCOUNT_USAGE视图返回空结果:当前使用的角色没有该schema的查询权限,找账号管理员授权即可。
内容的提问来源于stack exchange,提问作者spfr0727
相关产品推荐
相关产品推荐

