79413939

Date: 2025-02-05 07:30:07
Score: 0.5
Natty:
Report link

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;
Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @Fred
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: Matthew Cassell