Snowflake中用游标变量调用GET_OBJECT_REFERENCES函数报错求助
问题描述
我需要查询工作schema中视图的对象级依赖(表或其他视图),但由于组织策略限制没有ACCOUNT_USAGE访问权限,所以改用GET_OBJECT_REFERENCES函数获取每个视图的基础对象信息(依赖可能是多层级的,视图依赖其他视图最终指向表)。我编写了基于游标的查询来扫描所有视图,将依赖列表存入表时出现报错:
Uncaught exception of type 'STATEMENT_ERROR' on line 10 at position 8 : SQL compilation error: Object 'TEST_DB.MY_SCHEMA.V_VW_NM' does not exist or not authorized.
请问能否在GET_OBJECT_REFERENCES函数中使用游标变量?以下是我的代码:
CREATE OR REPLACE TABLE TEST_DB.MY_SCHEMA.OBJ_LINEAGE ( ref_obj_nm VARCHAR ); EXECUTE IMMEDIATE $$ DECLARE v_vw_nm VARCHAR; cur_vw_nm CURSOR FOR SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_type = 'VIEW'; BEGIN FOR c_vw_nm_rec IN cur_vw_nm DO v_vw_nm := c_vw_nm_rec.table_name; INSERT INTO OBJ_LINEAGE ( ref_obj_nm ) SELECT '('||LOWER(referenced_object_type)||') '||referenced_schema_name||'.'||referenced_object_name FROM TABLE ( GET_OBJECT_REFERENCES ( database_name => 'TEST_DB' ,schema_name => 'MY_SCHEMA' ,object_name => v_vw_nm ) ) ORDER BY referenced_schema_name, referenced_object_name; RETURN 1; END FOR; END; $$
问题分析与解决
1. GET_OBJECT_REFERENCES支持游标变量吗?
可以,但你的代码存在两个关键问题导致报错:
2. 报错原因及修复
- 循环提前终止:代码里的
RETURN 1放在FOR循环内部,第一次循环执行完就直接退出存储过程,后续视图根本没处理。如果游标中第一个视图就存在权限问题,会直接抛出错误。需将RETURN 1移到END FOR之后,确保所有视图都能被遍历。 - 缺失权限/存在性校验:游标从
INFORMATION_SCHEMA.TABLES读取的视图名中,可能存在你无权限访问或已被删除的视图。需要在调用GET_OBJECT_REFERENCES前添加异常捕获,跳过有问题的视图。
修复后的代码
CREATE OR REPLACE TABLE TEST_DB.MY_SCHEMA.OBJ_LINEAGE ( ref_obj_nm VARCHAR ); EXECUTE IMMEDIATE $$ DECLARE v_vw_nm VARCHAR; cur_vw_nm CURSOR FOR SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_type = 'VIEW'; BEGIN FOR c_vw_nm_rec IN cur_vw_nm DO v_vw_nm := c_vw_nm_rec.table_name; BEGIN INSERT INTO OBJ_LINEAGE ( ref_obj_nm ) SELECT '('||LOWER(referenced_object_type)||') '||referenced_schema_name||'.'||referenced_object_name FROM TABLE ( GET_OBJECT_REFERENCES ( database_name => 'TEST_DB' ,schema_name => 'MY_SCHEMA' ,object_name => v_vw_nm ) ) ORDER BY referenced_schema_name, referenced_object_name; EXCEPTION WHEN STATEMENT_ERROR THEN -- 可在此添加错误日志记录,例如: -- INSERT INTO VIEW_ERROR_LOG (VIEW_NAME, ERROR_MSG) VALUES (v_vw_nm, SQLERRM); CONTINUE; -- 跳过出错视图,继续处理下一个 END; END FOR; RETURN 1; -- 循环结束后再返回 END; $$
补充说明
GET_OBJECT_REFERENCES默认仅返回直接依赖,若需获取多层级的最终依赖表,需递归处理结果——比如循环调用函数处理返回的视图依赖,直到没有新视图出现。- 异常块中可添加日志记录,方便后续排查无权限或不存在的视图。
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

