因此,我有这个存储过程,它检查外键是否存在,如果不存在,则创建它。我需要在一个关于600+时代的脚本中运行它。最后,它应该显示跳过、成功和失败的总和。我不知道如何从准备好的陈述中计算成功/失败的数目。
我尝试将EXECUTE stmt;存储到var中,并将其封装为IF /END/END,但没有运气。如果这有帮助的话,ALTER不必是一个预先准备好的语句。
DELIMITER //
DROP PROCEDURE IF EXISTS `add_constraint_if_not_exists`//
SET @skippedCount = 0;
SET @successCount = 0;
SET @failCount = 0;
CREATE PROCEDURE add_constraint_if_not_exists (sourceDB varchar(64), sourceTable varchar(64), sourceColumn varchar(64), constraintName varchar(64), targetDB varchar(64), targetTable varchar(64), targetColumn varchar(64))
BEGIN
IF EXISTS (
SELECT *
FROM information_schema.table_constraints
WHERE
table_schema = sourceDB
AND table_name = sourceTable
AND constraint_name = constraintName
AND constraint_type = 'FOREIGN KEY'
LIMIT 1
) THEN
SET @skippedCount = @skippedCount + 1;
ELSE
SET @sql = CONCAT('ALTER TABLE `',sourceDB,'`.`',sourceTable,'` ADD CONSTRAINT ',constraintName,' FOREIGN KEY (`',sourceColumn,'`) REFERENCES `', targetDB,'`.`',targetTable, '` (`',targetColumn,'`)');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
/*
IF @result = -1 THEN
#SELECT @result;
SET @failCount = @failCount + 1;
ELSE
SET @successCount = @successCount + 1;
END IF
*/
END IF;
END //
DELIMITER ;
/*
ALTER TABLE `source_db`.`source_table`
ADD CONSTRAINT `fk`
FOREIGN KEY (`source_column`)
REFERENCES `target_db`.`target_table` (`target_column`);
*/
CALL add_constraint_if_not_exists ('source_db', 'source_table', 'source_column', 'fk', 'target_db', 'target_table', 'target_column');
SELECT @skippedCount,@successCount,@failCount;
发布于 2022-06-22 13:55:50
您可以使用SELECT @@error_count, @@warning_count
获取从最后一条语句中生成的错误或警告的数量。这适用于准备好的陈述。
演示:
mysql> set @sql = 'select 1/0';
Query OK, 0 rows affected (0.00 sec)
mysql> prepare s from @sql;
Query OK, 0 rows affected (0.00 sec)
Statement prepared
mysql> execute s;
+------+
| 1/0 |
+------+
| NULL |
+------+
1 row in set, 1 warning (0.00 sec)
mysql> select @@error_count, @@warning_count;
+---------------+-----------------+
| @@error_count | @@warning_count |
+---------------+-----------------+
| 0 | 1 |
+---------------+-----------------+
但老实说,我根本不会做你在存储过程中做的事情。我会通过运行模式更改的一些应用程序代码来完成这个任务。除了存储过程之外,任何其他接口都会为您提供更容易获取错误和警告的函数。
不管它的价值如何,我几乎从来没有将MySQL中的存储过程用于任何目的。它们很难开发或调试,性能很差,而且缺少很多特性。
我尝试了一下,发现错误会导致程序默认退出,就像Java或其他编程语言中的异常一样。因此,它永远不会到达增量@failCount
的语句。
为了解决这个问题,我尝试声明一个错误处理程序,它运行一个语句来增量@failCount
,然后退出该过程:
CREATE PROCEDURE ...
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @failCount = @failCount + 1;
...
在后面的过程中,我可以假设如果它通过了EXECUTE stmt
,那么它就成功了,所以我只是增加了成功计数。如果失败,就会触发退出处理程序。
...
ELSE
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @successCount = @successCount + 1;
END IF;
END//
有关此主题的更多信息,请阅读https://dev.mysql.com/doc/refman/8.0/en/declare-handler.html。
正如我前面所说,MySQL中的过程很难开发和调试。
https://stackoverflow.com/questions/72721849
复制相似问题