You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 03:53:11