A CONTINUE handler allows the execution to continue after a condition is encountered. When a condition occurs and a continue handler is invoked, control is passed to the handler. When the handler completes, control returns to the statement following the statement that raised the condition.
In IBM DB2, the DECLARE CONTINUE HANDLER statement is used to define actions that should be taken when specific SQL conditions or errors occur during procedure execution, while allowing the procedure to continue running.
When migrating from DB2 to Snowflake, SnowConvert AI transforms CONTINUE HANDLER declarations into equivalent Snowflake Scripting exception handling using EXCEPTION blocks with appropriate logic to continue execution.
DECLARECONTINUEHANDLERFOR condition_value [,...]
handler_action_statement;-- Where condition_value can be:-- SQLSTATE [VALUE] sqlstate_value-- condition_name-- SQLWARNING-- SQLEXCEPTION-- NOT FOUND
CREATEPROCEDURE error_handler_example()LANGUAGESQLBEGINDECLARE error_count INTDEFAULT0;DECLARECONTINUEHANDLERFOR SQLEXCEPTION
BEGINSET error_count = error_count +1;END;-- These statements may cause errorsINSERTINTO table1 VALUES(1/0);UPDATE table2 SET status ='completed'WHERE id =-1;DELETEFROM table3 WHERE invalid_column ='test';-- This will execute even if errors occurred aboveINSERTINTO error_summary VALUES(error_count);END;
CREATEORREPLACEPROCEDURE error_handler_example()RETURNSVARCHARLANGUAGESQLCOMMENT='{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "db2", "convertedOn": "01/15/2025" }}'AS$$
DECLARE
error_count INT := 0;
BEGIN
-- Statements in procedure body
INSERT INTO table1 VALUES (1/0);
UPDATE table2 SET status = 'completed' WHERE id = -1;
DELETE FROM table3 WHERE invalid_column = 'test';
-- This will execute even if errors occurred above
INSERT INTO error_summary VALUES (error_count);
EXCEPTION
WHEN OTHER CONTINUE THEN
error_count := error_count + 1;
END;
$$;
CREATEORREPLACEPROCEDURE cursor_handler_example()RETURNSVARCHARLANGUAGESQLCOMMENT='{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "db2", "convertedOn": "01/15/2025" }}'AS$$
DECLARE
v_id INT;
v_name VARCHAR(100);
v_done INT := 0;
cur1 CURSOR FOR
SELECT id, name FROM employees WHERE department = 'Sales';
BEGIN
OPEN cur1;
LOOP
BEGIN
FETCH cur1 INTO v_id, v_name;
EXCEPTION
WHEN NO_DATA_FOUND THEN
v_done := 1;
END;
IF (v_done = 1) THEN
BREAK;
END IF;
INSERT INTO sales_employees VALUES (v_id, v_name);
END LOOP;
CLOSE cur1;
END;
$$;
CREATEORREPLACEPROCEDURE warning_handler_example()RETURNSVARCHARLANGUAGESQLCOMMENT='{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "db2", "convertedOn": "01/15/2025" }}'AS$$
DECLARE
warning_count INT := 0;
BEGIN
-- Note: Snowflake doesn't distinguish warnings from errors in the same way
-- Warning handling may need to be implemented through validation logic
BEGIN
UPDATE products SET price = price * 1.1 WHERE category = 'Electronics';
EXCEPTION
WHEN OTHER THEN
warning_count := warning_count + 1;
INSERT INTO warning_log
VALUES (CURRENT_TIMESTAMP(), :SQLSTATE, :SQLCODE);
END;
BEGIN
DELETE FROM old_records WHERE record_date < CURRENT_DATE - 365;
EXCEPTION
WHEN OTHER THEN
warning_count := warning_count + 1;
INSERT INTO warning_log
VALUES (CURRENT_TIMESTAMP(), :SQLSTATE, :SQLCODE);
END;
INSERT INTO process_summary VALUES (warning_count);
END;
$$;
The exact behavior of DB2’s CONTINUE HANDLER cannot be fully replicated in Snowflake due to architectural differences:
Execution Continuation: In DB2, a CONTINUE HANDLER allows execution to continue from the statement immediately following the one that raised the condition. In Snowflake, each statement must be wrapped in its own exception block to achieve similar behavior.
Performance Impact: Wrapping multiple statements in individual exception blocks can impact performance compared to a single handler declaration.
Scope: DB2 CONTINUE HANDLERs apply to all statements in their scope. In Snowflake, exception handling must be more explicit.
DB2 allows multiple CONTINUE HANDLERs with different priorities. In Snowflake, handler precedence must be managed through explicit conditional logic using CASE statements.
DB2 allows declaring both CONTINUE and EXIT handlers in the same procedure block. However, Snowflake Scripting does not support mixing CONTINUE and EXIT handlers in the same EXCEPTION block. When this pattern is encountered, SnowConvert AI generates separate EXCEPTION blocks with an EWI warning.
CREATEORREPLACEPROCEDURE with_continueAndExit()RETURNSVARCHARLANGUAGESQLCOMMENT='{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "db2", "convertedOn": "01/15/2025" }}'AS$$
DECLARE
test_1 INTEGER DEFAULT 10;
BEGIN
test_1 := 1 / 0;
INSERT INTO error_test VALUES ('EXIT');
EXCEPTION
WHEN OTHER CONTINUE THEN
INSERT INTO error_test VALUES ('EXCEPTION')
!!!RESOLVE EWI!!! /*** SSC-EWI-0114 - MIXED CONTINUE AND EXIT EXCEPTION HANDLERS IN THE SAME BLOCK ARE NOT SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
EXCEPTION
WHEN OTHER EXIT THEN
CASE
WHEN (SQLSTATE = '20000') THEN
INSERT INTO error_test VALUES ('ERROR 2000')
END
END;
$$;