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> <pre class="brush:php;toolbar:false;">建立流程`test2`() 開始 IF(存在時選擇案例( 選擇1 來自知名作品 WHERE titleId NOT IN(從 titlebasics 中選擇 tconst)) 然後 1 否則 0 結束 ) = 1 然後 ALTER TABLEknownfortitles ADD is_in_titlebasics BOOL; 別的 選擇空; 萬一; 結束</pre>此程序將列
is_in_titlebasics
加到表knownfortitles
中,這就是我想要發生的事情,所以這很好。此時,我完全迷失了,不知道為什麼我的實際存儲過程不起作用,因為它基本上是最後兩個過程的組合。我暫時忽略了我希望儲存過程執行的第二部分,因為我遇到的錯誤似乎將第一個<code>CONCAT</code>語句視為問題。</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)
欄位。