Snowflake 脚本 - EXECUTE IMMEDIATE 多个语句来删除没有循环/游标的表

Luk*_*zda 3 snowflake-cloud-data-platform

目标是仅使用 SQL 而不使用游标/循环来删除与特定命名模式匹配的多个表:

设置:

CREATE TABLE tab_1(i INT);
CREATE TABLE tab_2(i INT);
CREATE TABLE tab_3(i INT);
CREATE TABLE tab_4(i INT);
CREATE TABLE tab_5(i INT);
Run Code Online (Sandbox Code Playgroud)

通常可以通过先生成查询来完成:

SELECT LISTAGG(CONCAT('DROP TABLE IF EXISTS ', TABLE_NAME, ';', CHAR(10)) ,'')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
  AND TABLE_SCHEMA = 'PUBLIC'
  AND TABLE_NAME ILIKE 'TAB!_%' ESCAPE '!'
GROUP BY GROUPING SETS(());
/*
DROP TABLE IF EXISTS TAB_1; 
DROP TABLE IF EXISTS TAB_2; 
DROP TABLE IF EXISTS TAB_3; 
DROP TABLE IF EXISTS TAB_4; 
DROP TABLE IF EXISTS TAB_5; 
*/
Run Code Online (Sandbox Code Playgroud)

然后需要复制并运行输出。此手动步骤是不必要的,应该避免。

这个想法是使用SELECT INTOEXECUTE IMMEDIATE调用生成的查询:

DECLARE 
    QUERY STRING;
BEGIN
    SELECT LISTAGG(CONCAT('DROP TABLE IF EXISTS ', TABLE_NAME, ';', CHAR(10)), '')
    INTO :QUERY
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_TYPE = 'BASE TABLE'
      AND TABLE_SCHEMA = 'PUBLIC'
      AND TABLE_NAME ILIKE 'TAB!_%' ESCAPE '!'
    GROUP BY GROUPING SETS(());

  QUERY := COALESCE(QUERY, 'SELECT ''No tables found''');

  EXECUTE IMMEDIATE :QUERY;
  RETURN :QUERY;
END;
Run Code Online (Sandbox Code Playgroud)

这不可能:

不支持在单个 API 调用中使用多个 SQL 语句;请改为对每个语句使用一个 API 调用。

Luk*_*zda 6

答案是用 BEGIN END 块包装生成的代码:

DECLARE 
    QUERY STRING;
BEGIN
    SELECT CONCAT('BEGIN', CHAR(10)
             ,LISTAGG(CONCAT('DROP TABLE IF EXISTS ', TABLE_NAME, ';', CHAR(10)), '')
             ,'END')
    INTO :QUERY
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_TYPE = 'BASE TABLE'
      AND TABLE_SCHEMA = 'PUBLIC'
      AND TABLE_NAME ILIKE 'TAB!_%' ESCAPE '!'
    GROUP BY GROUPING SETS(());

  QUERY := COALESCE(QUERY, 'SELECT ''No tables found''');

  EXECUTE IMMEDIATE :QUERY;
  RETURN :QUERY;
END;
Run Code Online (Sandbox Code Playgroud)

输出:

BEGIN
DROP TABLE IF EXISTS TAB_1;
DROP TABLE IF EXISTS TAB_2;
DROP TABLE IF EXISTS TAB_3;
DROP TABLE IF EXISTS TAB_4;
DROP TABLE IF EXISTS TAB_5;
END

SHOW TABLES LIKE 'TAB_%';
-- no resultset
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

第二次运行:

在此输入图像描述