Thanks to P. Salmon, I learned that the problem was running the IF ... THEN
statement through the prepared statement. This is impossible. After some tinkering, I came up with the following program, which works exactly as I want. I hope I can help some people who have similar problems to me.
DELIMITER $$ USE `<schema>`$$ CREATE DEFINER=`Setupinfolab`@`%` PROCEDURE `CheckValueExistsInBaseTable`( IN checkedTable VARCHAR(100), IN referencedBaseTable VARCHAR(100), IN checkedCol VARCHAR(100), IN referencedCol VARCHAR(100) ) BEGIN SET @checkedTable = checkedTable; SET @referencedBaseTable = referencedBaseTable; SET @checkedCol = checkedCol; SET @referencedCol = referencedCol; SET @new_column_name = CONCAT('is_in_', referencedBaseTable); -- Check if there are indeed values in checkedCol that are not present in referencedCol SET @query1 = CONCAT(' SELECT CASE WHEN EXISTS( SELECT 1 FROM ',@checkedTable,' WHERE ',@checkedCol,' NOT IN (SELECT ',@referencedCol,' FROM ',@referencedBaseTable,')) THEN 1 ELSE 0 END INTO @proceed'); -- Adding the boolean column SET @query2 = CONCAT(' ALTER TABLE ',@checkedTable,' ADD ',@new_column_name,' BOOL;'); -- Inserting boolean values in new column according to presence in referencedCol SET @query3 = CONCAT(' UPDATE ',@checkedTable,' SET ',@new_column_name,' = ( CASE WHEN EXISTS( SELECT * FROM ',@referencedBaseTable,' WHERE ',@referencedBaseTable,'.',@referencedCol,' = ',@checkedTable,'.',@checkedCol,') THEN true ELSE false END ) WHERE id<>0;'); PREPARE stmt1 FROM @query1; EXECUTE stmt1; IF @proceed = 1 THEN PREPARE stmt2 FROM @query2; EXECUTE stmt2; PREPARE stmt3 FROM @query3; EXECUTE stmt3; SELECT CONCAT(@new_column_name,' column added to table ', @checkedTable,'.') AS 'Message: Done'; DEALLOCATE PREPARE stmt2; DEALLOCATE PREPARE stmt3; ELSE SELECT 'All values are present in base table. Adding column is thus unnecessary.' AS 'Message: UNNECESSARY'; END IF; DEALLOCATE PREPARE stmt1; END$$ DELIMITER ; ;
However, I would like to point out that I haven't added a TRY ... CATCH
or anything to stop the program from throwing an error. This is just the bare minimum to make it work.
Calling process
CALL CheckValueExistsInBaseTable( 'knownfortitles', 'titlebasics', 'titleId', 'tconst' );
Return message confirmation:
or message warning:
Only in the first case, the TINYINT(1)
column will be added as needed.