我有一个删除所有表的脚本。
SET FOREIGN_KEY_CHECKS = 0;
SET @tables = NULL;
SELECT GROUP_CONCAT(table_schema, '.', table_name) INTO @tables
FROM information_schema.tables
WHERE table_schema = 'mydb';
SET @tables = CONCAT('DROP TABLE ', @tables);
PREPARE stmt FROM @tables;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET FOREIGN_KEY_CHECKS = 1;
它只能完美运行一次 - 当至少存在一个表时。 第二次运行给我一个错误:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1 SQL.sql 9 1
我正在尝试使用 IF 语句,但它仍然不起作用:
IF @tables IS NOT NULL THEN
SET @tables = CONCAT('DROP TABLE ', @tables);
PREPARE stmt FROM @tables;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'if @tables IS NOT NULL THEN SET @tables = CONCAT('DROP TABLE ', @tables)' at line 1 SQL.sql 8 1
在这种情况下使用 IF 的正确方法是什么?
最佳答案
当您为 session 变量赋值并在查询中使用该值时
它的值(value)将取代占位符。而由于这个原因,
SELECT GROUP_CONCAT(table_schema, '.', table_name) INTO @tables
成为
SELECT GROUP_CONCAT(table_schema, '.', table_name) INTO NULL
这完全没有意义。
相反,您应该直接使用变量而不预先设置它的值。
所以不要使用
SET @tables = NULL;
其次,语句 block 不能直接由数据库引擎编译,除非它们的范围定义在 block 下。这通常是使用存储过程或触发器完成的。如果在过程中,它们必须在 BEGIN
和 END
之间。
所以下面是错误的:
IF @tables IS NOT NULL THEN
SET @tables = CONCAT('DROP TABLE ', @tables);
PREPARE stmt FROM @tables;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
您应该遵循为存储过程定义的语法来使用作用域变量。
请引用我对类似问题的回答,如下所示:
关于mysql - 检查存储过程中的 var 是否为 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21825833/