2014-02-17 21 views
1

我有一个删除所有表的脚本。在存储过程中检查var为NULL

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正确的方法这个案例?

回答

2

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

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

成为

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

它没有任何意义可言。

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

SET @tables = NULL; 

其次,语句块不能直接通过数据库引擎,除非他们的范围块下定义编译。这通常是使用存储过程或触发器完成的。如果在程序中,它们必须介于BEGINEND之间。

所以下面是错误的:

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 Syntax error.
  2. 另请参考:Variables declaration and scope