IF (SELECT CASE WHEN EXISTS( 选择1 来自知名作品 WHERE titleId NOT IN(从 titlebasics 中选择 tconst)) 然后 1 否则 0 结束 ) = 1 然后 ALTER TABLEknownfortitles ADD is_in_titlebasics BOOL; 别的 选择空; END IF</pre> <p>可能的代码是正确的,我知道这一点是因为我使用了下面的第二个过程,该过程利用了这个恶意的代码块。</p>创建过程`test2`() 开始 IF(存在时选择案例( 选择1 来自知名作品 WHERE titleId NOT IN(从 titlebasics 中选择 tconst)) 然后 1 否则 0 结束 ) = 1 然后 ALTER TABLEknownfortitles ADD is_in_titlebasics BOOL; 别的 选择空; 万一; 结束</pre>此过程将列
is_in_titlebasics
添加到表knownfortitles
中,这就是我想要发生的事情,所以这很好。此时,我完全迷失了,不知道为什么我的实际存储过程不起作用,因为它基本上是最后两个过程的组合。我暂时忽略了我希望存储过程执行的第二部分,因为我遇到的错误似乎将第一个CONCAT
语句视为问题。</p> <p>我希望这个问题非常明显,但我只是忽略了。欢迎任何帮助,提前致谢!</p>
P粉7983434152023-09-07 00:02:02
感谢 P. Salmon,我了解到问题是通过准备好的语句运行 IF ... THEN
语句。这不可能。经过一番修改后,我想出了以下程序,它的工作原理与我想要的完全一样。我希望我可以帮助一些与我遇到类似问题的人。
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 ; ;
但是,我想指出的是,我还没有添加 TRY ... CATCH
或任何阻止程序抛出错误的内容。这只是使其发挥作用的最低限度。
调用过程
CALL CheckValueExistsInBaseTable( 'knownfortitles', 'titlebasics', 'titleId', 'tconst' );
返回消息确认:
或消息警告:
仅在第一种情况下,才会根据需要添加 TINYINT(1)
列。