Because schemachange uses the Snowflake Python connector's execute_string() method, it splits SQL on semicolons (;) client-side. This breaks Snowflake Scripting blocks (like BEGIN...END in Tasks or Anonymous blocks) because the block is split into invalid fragments before reaching Snowflake.
Solutions
Option 1: Single Statement (Best for simple tasks)
Remove the BEGIN...END wrapper if the task only executes one statement.
Option 2: EXECUTE IMMEDIATE with $$ (Best for multi-statement blocks)
Wrap your block in EXECUTE IMMEDIATE using dollar-quoted delimiters ($$). This makes the entire block appear as a single statement to schemachange.
CREATE OR REPLACE TASK my_task
WAREHOUSE = my_warehouse
SCHEDULE = '5 minutes'
AS
EXECUTE IMMEDIATE $$
BEGIN
START TRANSACTION;
DELETE FROM archive WHERE created_at < DATEADD(year, -1, CURRENT_DATE);
INSERT INTO archive SELECT * FROM staging;
TRUNCATE TABLE staging;
COMMIT;
END;
$$;
Option 3: Call a Stored Procedure (Best for complex logic)
Encapsulate the logic in a stored procedure and have the task call it using CALL.
CREATE OR REPLACE TASK my_task
WAREHOUSE = my_warehouse
SCHEDULE = '5 minutes'
AS
EXECUTE IMMEDIATE $$
BEGIN
START TRANSACTION;
DELETE FROM archive WHERE created_at < DATEADD(year, -1, CURRENT_DATE);
INSERT INTO archive SELECT * FROM staging;
TRUNCATE TABLE staging;
COMMIT;
END;
$$;