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 INTO并EXECUTE 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 调用。
答案是用 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)
第二次运行: