如何在Snowflake中创建带动态DDL的SQL匿名块倒序恢复任务
实现思路
不用JavaScript存储过程的前提下,直接用Snowflake原生支持的Snowflake Scripting语法封装逻辑即可,整个实现可以包装为单条SQL语句,完全适配Jenkins单文件仅允许单条SQL的配置限制,核心逻辑为:
- 按任务编号从大到小倒序循环,先恢复高编号子任务,最后恢复根任务TSK_1,符合Snowflake任务依赖的恢复规则
- 循环中动态拼接ALTER TASK语句,通过
EXECUTE IMMEDIATE执行DDL - 逻辑封装在匿名块中,执行后不会残留额外数据库对象,无需后续清理
可直接使用的单SQL脚本
以下代码为完整单条可执行语句,直接放到Jenkins的SQL执行步骤中即可运行,无需提前创建任何数据库对象:
EXECUTE IMMEDIATE $$ DECLARE -- 若后续任务总数变动,仅需修改此处的最大编号值即可 MAX_TASK_ID INT := 27; task_alter_stmt VARCHAR; BEGIN -- 从最大编号倒序遍历到1,保证TSK_1最后执行RESUME FOR task_seq IN MAX_TASK_ID DOWN TO 1 LOOP task_alter_stmt := 'ALTER TASK TSK_' || task_seq::VARCHAR || ' RESUME'; EXECUTE IMMEDIATE task_alter_stmt; END LOOP; RETURN '所有任务已按依赖顺序恢复完成'; END; $$;
可选:可复用存储过程版本
如果需要在多个流程中重复调用该逻辑,可以提前创建一次永久存储过程,后续Jenkins步骤仅需单条CALL语句即可完成操作:
-- 以下建过程语句仅需在数据库中执行一次 CREATE OR REPLACE PROCEDURE SP_RESUME_TSK_CHAIN(MAX_TASK_ID INT) RETURNS VARCHAR LANGUAGE SQL EXECUTE AS OWNER AS $$ DECLARE task_alter_stmt VARCHAR; BEGIN FOR task_seq IN MAX_TASK_ID DOWN TO 1 LOOP task_alter_stmt := 'ALTER TASK TSK_' || task_seq::VARCHAR || ' RESUME'; EXECUTE IMMEDIATE task_alter_stmt; END LOOP; RETURN '共恢复' || MAX_TASK_ID || '个任务,根任务TSK_1已最后启用'; END; $$;
后续Jenkins执行时仅需放置单条调用语句即可:
CALL SP_RESUME_TSK_CHAIN(27);
注意事项
- 执行上述脚本使用的数据库账号,需要拥有所有目标TSK_x任务的ALTER权限
- 倒序执行的逻辑完全符合Snowflake任务依赖要求:恢复有依赖关系的任务链时,必须先恢复子任务,最后恢复根任务,直接先恢复父任务会抛出依赖错误
- 如果任务名称带schema/database前缀,只需要修改拼接
task_alter_stmt的部分,加上对应前缀即可,例如'ALTER TASK MY_DB.MY_SCHEMA.TSK_' || task_seq::VARCHAR || ' RESUME'
提示:如果需要验证语句拼接是否正确,可以在循环里先加一句
RETURN task_alter_stmt;做单步调试,确认语句格式正确后再去掉调试语句正式执行。
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

