如何在Snowflake中异步调用存储过程并获取返回值
在Snowflake存储过程中异步调用另一个存储过程并获取返回值
核心实现方案
Snowflake中异步调用存储过程后会返回查询ID(Query ID),通过这个ID结合RESULT_SCAN函数,就能直接获取异步任务的返回结果,无需用表中转,是最简洁的实现方式。
1. 先确保目标存储过程bar可正常返回结果
示例bar的基础实现:
CREATE OR REPLACE PROCEDURE bar() RETURNS VARCHAR LANGUAGE SQL AS $$ BEGIN RETURN '异步调用成功:来自bar的返回值'; END; $$;
2. 在foo中正确实现异步调用与结果获取
你的第一种方法出错,核心原因是没把CALL ... ASYNC放在TABLE()中捕获查询ID。以下是正确的foo实现:
CREATE OR REPLACE PROCEDURE foo() RETURNS VARCHAR LANGUAGE SQL AS $$ DECLARE async_query_id VARCHAR; bar_return_value VARCHAR; BEGIN -- 异步调用bar,捕获返回的查询ID SELECT query_id INTO async_query_id FROM TABLE(CALL bar() ASYNC); -- 可选:等待异步任务执行完成(根据业务需求决定是否等待) -- 可指定等待状态,比如'SUCCESS'仅等待成功,'FAILED'等待失败,'ANY'等待任意状态 CALL SYSTEM$WAIT_FOR_QUERY(async_query_id, 'SUCCESS'); -- 通过RESULT_SCAN获取bar的返回值 SELECT $1 INTO bar_return_value FROM TABLE(RESULT_SCAN(async_query_id)); RETURN '获取到bar的返回值:' || bar_return_value; END; $$;
3. 关键细节说明
- 异步语法要求:
CALL <存储过程> ASYNC必须包裹在TABLE()中,才能通过SELECT提取查询ID,这是你最初语法错误的核心原因。 - 结果有效期:
RESULT_SCAN默认可访问最近7天内的查询结果,满足绝大多数场景需求。 - 权限要求:调用
foo的角色需拥有bar的EXECUTE权限,以及RESULT_SCAN的使用权限。
错误方案分析
- OUT参数失败原因:异步调用的存储过程在独立会话中执行,与调用方
foo的上下文不共享,因此OUT参数无法传递值,这种方案本身不适用异步场景。 - 临时表方案优化:如果
bar返回大结果集,可改用会话级临时表(CREATE TEMP TABLE)存储结果,异步调用完成后直接读取临时表,但仅推荐给大结果集场景,小结果集用RESULT_SCAN更高效。
内容的提问来源于stack exchange,提问作者Kal
相关产品推荐
相关产品推荐

