如何在无ACCOUNT_USAGE权限时统计Snowflake跨库MY_TABLE行数?
统计Snowflake多数据库中同名表MY_TABLE的行数
由于没有ACCOUNT_USAGE架构权限,无法通过全局视图直接查询,可通过以下两种方式实现需求:
一、指定数据库列表(适合数据库数量少的场景)
手动列出你有权限访问的目标数据库,用UNION ALL拼接每个数据库的information_schema.tables查询:
SELECT table_catalog, table_name, row_count FROM DB1.information_schema.tables WHERE table_name = 'MY_TABLE' UNION ALL SELECT table_catalog, table_name, row_count FROM DB2.information_schema.tables WHERE table_name = 'MY_TABLE' UNION ALL SELECT table_catalog, table_name, row_count FROM DB3.information_schema.tables WHERE table_name = 'MY_TABLE';
说明:需确保你对每个指定数据库的information_schema.tables有读取权限,row_count是Snowflake维护的统计值,非实时精确数。
二、动态遍历有权限的数据库(适合数据库数量多的场景)
通过创建存储过程,自动遍历当前用户有权限访问的所有非系统数据库,生成并执行查询:
基于统计值row_count的版本
CREATE OR REPLACE PROCEDURE GET_ALL_MY_TABLE_ROW_COUNTS() RETURNS TABLE(table_catalog VARCHAR, table_name VARCHAR, row_count NUMBER) LANGUAGE SQL AS $$ DECLARE res RESULTSET; query_str VARCHAR := ''; db_cursor CURSOR FOR SELECT catalog_name FROM information_schema.databases WHERE catalog_name != 'SNOWFLAKE'; BEGIN FOR db IN db_cursor DO IF query_str != '' THEN query_str := query_str || ' UNION ALL '; END IF; query_str := query_str || 'SELECT ''' || db.catalog_name || ''' AS table_catalog, ''MY_TABLE'' AS table_name, row_count FROM ' || db.catalog_name || '.information_schema.tables WHERE table_name = ''MY_TABLE'''; END FOR; res := (EXECUTE IMMEDIATE query_str); RETURN TABLE(res); END; $$; -- 调用存储过程获取结果 CALL GET_ALL_MY_TABLE_ROW_COUNTS();
精确行数(COUNT(*))版本
如果需要实时精确的行数,可将存储过程中的查询逻辑改为执行COUNT(*),注意替换表对应的schema(示例中用PUBLIC,需根据实际调整):
CREATE OR REPLACE PROCEDURE GET_ALL_MY_TABLE_EXACT_ROW_COUNTS() RETURNS TABLE(table_catalog VARCHAR, table_name VARCHAR, row_count NUMBER) LANGUAGE SQL AS $$ DECLARE res RESULTSET; query_str VARCHAR := ''; db_cursor CURSOR FOR SELECT catalog_name FROM information_schema.databases WHERE catalog_name != 'SNOWFLAKE'; BEGIN FOR db IN db_cursor DO IF query_str != '' THEN query_str := query_str || ' UNION ALL '; END IF; -- 替换PUBLIC为MY_TABLE实际所在的schema query_str := query_str || 'SELECT ''' || db.catalog_name || ''' AS table_catalog, ''MY_TABLE'' AS table_name, (SELECT COUNT(*) FROM ' || db.catalog_name || '.PUBLIC.MY_TABLE) AS row_count'; END FOR; res := (EXECUTE IMMEDIATE query_str); RETURN TABLE(res); END; $$; -- 调用存储过程 CALL GET_ALL_MY_TABLE_EXACT_ROW_COUNTS();
说明:
- 执行存储过程前需确保你有创建存储过程的权限,以及访问目标数据库和对应表的权限
COUNT(*)版本会扫描每个表的数据,数据量较大时性能开销较高,需谨慎使用
内容的提问来源于stack exchange,提问作者Dudelstein
相关产品推荐
相关产品推荐

