表名为变量的错误情况

一般来说,MySQL存储过程中是不支持表名作为变量名的
如下语句就会有问题

declare v_table_name varchar(50);

select * from v_table_name;

这样的话MySQL会报错,错误是在当前库下没有 v_table_name 这张表。如果没有报错,可能是当前库下存在 v_table_name 这张表,但是这样和我们预期想要达到的效果可定是不一样的。

解决方法

使用concat连接的方式处理sql语句

declare v_table_name varchar(50);

set @sql=CONCAT('select * from ',v_table_name);
PREPARE stmt from @sql;
EXECUTE stmt;

按上述语句执行即可,完成当表名为变量时存储过程应该如何去满足。

将表(表名为变量)中数据重新赋值另一个变量

先看我试了好几中的错误方法,以下几种方式均为错误

第一种错误

declare v_table_name varchar(50);
declare v_num int;

set @sql=CONCAT('select count(0) into ', v_num  ,' from ',v_table_name);
PREPARE stmt from @sql;
EXECUTE stmt;

报错,这里的连接不是将v_num这个变量值拼接,而是拼接了null这个字符串,那就会报错

第二种错误

既然第一种错误变成了拼接null,于是我就直接写入了sql中

declare v_table_name varchar(50);
declare v_num int;

set @sql=CONCAT('select count(0) into v_num from ',v_table_name);
PREPARE stmt from @sql;
EXECUTE stmt;

然而还是报错,这次时报错 v_num 这边变量没有定义,这个问题我到现在还是没有理解,明明上面定义了,但是在concat中还是获取不到这个变量的定义,我感觉是 可能和编程语言中的局部变量和全域变量的理解差不多把。
查阅资料后确实是这么说的 declare是局部变量,这样的话就是说这个局部变量无法影响到@sql这里去,而且set @sql 这个是会话变量,也就是全局变量。

正确的方式

后来查看了许多资料,才发现可以这样赋值,也是相当的简单了

declare v_table_name varchar(50);

set @sql=CONCAT('select count(0) into @v_num from ',v_table_name);
PREPARE stmt from @sql;
EXECUTE stmt; 

select @v_num;

按上述方式可以直接将 记录数复制给 @v_num 这个变量,其实这个变量我并没有定义,但是确实是可以获取到的,但是会话变量的定义 应该是 set @v_num int;
后来我有用测试表试了一下,确实在没有set @v_num的时候 直接使用into @v_num 可以将数据复制给@v_num会话变量。感觉上是在into @ 的时候 默认了将变量设置为会话变量