阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

MariaDB 10.0 和 MariaDB 10.1 存储过程中 PREPARE FROM EXECUTE 区别

198次阅读
没有评论

共计 1976 个字符,预计需要花费 5 分钟才能阅读完成。

前景:

有一个更新表分区的存储过程,在 MariaDB10.1.12 下,是能正常运行的。某些业务要求,我同步了这个存储过程到另一台服务器的数据库中,版本为 MariaDB10.0.19,这个存储过程执行报错!

存储过程如下:

 CREATE  PROCEDURE `proc_accesslog_partition_add`(in dbname VARCHAR(20), in tablename VARCHAR(30), in accdate VARCHAR(20))

BEGIN
— dbname 数据库名;tablename:表名;accdate:日期
DECLARE conditionSql VARCHAR(2000);
 DECLARE alterStr VARCHAR(1000);
 SET conditionSql = CONCAT(“SELECT * FROM information_schema.partitions where table_schema='”,dbname,”‘ and table_name='”,tablename,”‘ AND PARTITION_NAME=’p”,accdate,”‘”);
 SET alterStr = CONCAT(“ALTER TABLE “,tablename,” ADD PARTITION (PARTITION p”,accdate,” VALUES LESS THAN (TO_DAYS(‘”,accdate,”‘)))”);

 SET @STR=CONCAT(“IF NOT EXISTS(“,conditionSql,”) THEN “,alterStr,”;END IF;”);
 PREPARE mainStmt FROM @STR;
 EXECUTE mainStmt;

END

在 10.1 下,这个过程是能正常执行的。

但是在 10.0 下,它会抱如下错误:

[SQL]CALL proc_test(‘ad_warehouse’,’t_access_log_30′,’20160323′);
[Err] 1064 – You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘IF NOT EXISTS(SELECT * FROM information_schema.partitions where table_schema=’a’ at line 1

MySQL prepare 语法:
PREPARE statement_name FROM preparable_SQL_statement; /* 定义 */
EXECUTE statement_name [USING @var_name [, @var_name] …]; /* 执行预处理语句 */
{DEALLOCATE | DROP} PREPARE statement_name /* 删除定义 */ ;

重新修改存储过程:

BEGIN
— dbname 数据库名;tablename:表名;accdate:日期
DECLARE num INT;
 SET @if_sql = CONCAT(“SELECT count(*) INTO @record FROM information_schema.partitions where table_schema='”,dbname,”‘ and table_name='”,tablename,”‘ AND PARTITION_NAME=’p”,accdate,”‘”);
 SET @alter_sql = CONCAT(“ALTER TABLE “,tablename,” ADD PARTITION (PARTITION p”,accdate,” VALUES LESS THAN (TO_DAYS(‘”,accdate,”‘)))”);
 PREPARE ifStmt FROM @if_sql;
 EXECUTE ifStmt;
 deallocate prepare ifStmt;

 SET num=@record;
 IF num=0 THEN
 PREPARE alterStmt FROM @alter_sql;
 EXECUTE alterStmt;
 deallocate prepare alterStmt;
 END IF;

END

这个过程能在 10.0 和 10.1 下执行成功。

这个结果说明

1、mariaDB10.0 的 prepare from execute 语法中,preparable_SQL_statement 只支持简单的 SQL 语句,不支持 if exists 等复杂语句。

2、动态 SQL 语法执行,需要 PREPARE FROM EXECUTE 来实现。

3、在存储过程需要获取上一个结果作为条件,用 INTO,但有一点需要记住,EXECUTE 只把 @开头的当做参数。

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计1976字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中