MySQL存储过程新增分区报ERROR 1064 (42000)错误求解
问题原因
核心错误来自两处MySQL语法规则的误用:
- 混淆了局部变量和用户会话变量。你通过
DECLARE ddl VARCHAR(512)声明的是存储过程内部的局部变量,作用域仅在当前存储过程范围内;而@ddl是带@前缀的用户会话变量,作用域是当前数据库连接的整个生命周期,你全程没有给@ddl赋值,它默认值为NULL,因此PREPARE stmt FROM @ddl实际是解析NULL作为SQL语句,自然抛出near 'NULL'的语法错误。 PREPARE语句的语法限制:MySQL要求PREPARE待执行的SQL必须是用户会话变量或者字符串字面量,不支持直接使用DECLARE声明的局部变量作为参数。另外你第二种写法中用?作为表名、分区名的占位符也不符合规则,动态SQL的参数占位符仅可用于传入值,不能用于替换表名、字段名、分区名这类标识符。
解决方案
将拼接完成的SQL直接赋值给用户会话变量@ddl再执行即可,修正后的存储过程代码如下:
DELIMITER // DROP PROCEDURE IF EXISTS cr_par // CREATE PROCEDURE cr_par ( IN p_table VARCHAR(256), IN p_date DATE ) BEGIN DECLARE par_name VARCHAR(20) DEFAULT ''; DECLARE par_no INT DEFAULT 0; DECLARE lt_value INT DEFAULT 0; SET par_no = TO_DAYS(p_date) + 1; SET par_name = CONCAT('p', par_no); SET lt_value = par_no + 1; -- 直接赋值给用户会话变量@ddl,无需声明局部变量ddl SET @ddl = CONCAT('ALTER TABLE ', p_table, ' ADD PARTITION (PARTITION ', par_name, ' VALUES LESS THAN (', lt_value, '))'); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT @ddl AS ddl; END // DELIMITER ;
验证说明
修正后调用存储过程即可正常执行,你之前注释执行部分拿到的DDL本身完全合法,只是变量引用错误导致正确的SQL没有被传入PREPARE语句。
内容的提问来源于stack exchange,提问作者0xd313
相关产品推荐
相关产品推荐

