1

我有一个删除所有表的脚本。

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; 

它只能完美运行一次 - 当至少存在一个表时。第二次运行给我一个错误:

您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行 SQL.sql 9 1 的“NULL”附近使用正确的语法

我正在尝试使用 IF 语句,但它仍然不起作用:

IF @tables IS NOT NULL THEN
  SET @tables = CONCAT('DROP TABLE ', @tables);
  PREPARE stmt FROM @tables;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;
END IF;

您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行 SQL.sql 8 1 的“if @tables IS NOT NULL THEN SET @tables = CONCAT('DROP TABLE ', @tables)”附近使用正确的语法

在这种情况下使用 IF 的正确方法是什么?

4

1 回答 1

2

当您为会话变量分配一个值并在查询中使用它时,
它的值将替换占位符。并且由于这个原因,

SELECT GROUP_CONCAT(table_schema, '.', table_name) INTO @tables

变成

SELECT GROUP_CONCAT(table_schema, '.', table_name) INTO NULL  

这根本没有任何意义。

相反,您应该直接使用变量而不预先设置其值。
所以不要使用

SET @tables = NULL;

其次,语句块不能由数据库引擎直接编译,除非它们的范围定义在一个块下。这通常使用存储过程或触发器来完成。如果在一个过程中,它们必须在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;

您应该遵循为存储过程定义的语法来使用范围变量。

请参阅我对类似问题的回答,如下所述:

  1. MySQL 语法错误
  2. 另请参阅:变量声明和范围
于 2014-02-17T10:24:07.070 回答