As was stated in the answer by @Fred, the issue was that a FOR
clause only accepts a static cursor, while we need a dynamic cursor as we want to pass the table and column names as strings to generate the cursor. As such, we needed to manually generate a cursor and use a WHILE
loop to perform the iteration procedure.
The following procedure performs the correct calculation
CREATE PROCEDURE db_name.dynamic_flags_procedure (
IN col_name VARCHAR(32),
IN tbl_name VARCHAR(32)
)
BEGIN
DECLARE hc1 VARCHAR(32);
DECLARE sql_stmt VARCHAR(2048);
DECLARE distinct_stmt VARCHAR(128); -- cursor requirement
DECLARE rslt CURSOR FOR stmt; -- cursor requirement
-- create first part of sql_stmt, creating the table and selecting the column 'FIRSTNAME'
SET sql_stmt = 'CREATE MULTISET VOLATILE TABLE FLAG_TABLE AS (
SELECT
FIRSTNAME';
-- get the unique elements in col_name to loop over
-- first 'FETCH' must be included here, not within the 'WHILE' loop
SET distinct_stmt = 'SELECT DISTINCT ' || col_name || ' AS distinct_values FROM ' || tbl_name;
PREPARE stmt FROM distinct_stmt;
OPEN rslt;
FETCH rslt INTO hc1;
WHILE (SQLCODE = 0)
DO
-- add the string to create flag column to sql_stmt
SET sql_stmt = sql_stmt || ', CASE WHEN ' || col_name || ' = ' || hc1 || ' THEN 1 ELSE 0 END AS "' || hc1 || '_f"';
-- get next distinct value
FETCH rslt INTO hc1;
END WHILE;
CLOSE rslt;
-- add final part to the sql_stmt
SET sql_stmt = sql_stmt || ' FROM ' || tbl_name || ') WITH DATA ON COMMIT PRESERVE ROWS;';
EXECUTE IMMEDIATE sql_stmt;
END;
CALL db_name.dynamic_flags_procedure('EMPLOYMENT_LENGTH_YEARS', 'PRACTICE_DATA');
SELECT * FROM FLAG_TABLE;