简单的用set或者declare语句定义变量,然后直接作为sql的表名是不行的,mysql会把变量名当作表名。在其他的sql数据库中也是如此,mssql的解决方法是将整条sql语句作为变量,其中穿插变量作为表名,然后用sp_executesql调用该语句。

这在mysql5.0之前是不行的,5.0之后引入了一个全新的语句,可以达到类似sp_executesql的功能(仅对procedure有效,function不支持动态查询):

PREPARE stmt_name FROMpreparable_stmt;EXECUTE stmt_name [USING @var_name [, @var_name]...];

{DEALLOCATE | DROP} PREPARE stmt_name;

为了有一个感性的认识,

下面先给几个小例子:

mysql> PREPARE stmt1 FROM ‘SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse‘;

mysql> SET @a = 3;

mysql> SET @b = 4;

mysql> EXECUTE stmt1 USING @a, @b;+------------+

| hypotenuse |

+------------+

| 5 |

+------------+

mysql> DEALLOCATE PREPAREstmt1;

mysql> SET @s = ‘SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse‘;

mysql> PREPARE stmt2 FROM @s;

mysql> SET @a = 6;

mysql> SET @b = 8;

mysql> EXECUTE stmt2 USING @a, @b;+------------+

| hypotenuse |

+------------+

| 10 |

+------------+

mysql> DEALLOCATE PREPARE stmt2;

如果你的MySQL 版本是 5.0.7 或者更高的,你还可以在 LIMIT 子句中使用它,示例如下:

mysql> SET @a=1;mysql> PREPARE STMT FROM "SELECT * FROMtbl LIMIT ?";

mysql> EXECUTE STMT USING @a;

mysql> SET @skip=1; SET @numrows=5;

mysql> PREPARE STMT FROM "SELECT * FROMtbl LIMIT ?, ?";

mysql> EXECUTE STMT USING @skip, @numrows;

使用 PREPARE 的几个注意点:

A:PREPARE stmt_name FROM preparable_stmt;预定义一个语句,并将它赋给 stmt_name ,tmt_name 是不区分大小写的。

B: 即使 preparable_stmt 语句中的 ? 所代表的是一个字符串,你也不需要将 ? 用引号包含起来。

C: 如果新的 PREPARE 语句使用了一个已存在的 stmt_name ,那么原有的将被立即释放! 即使这个新的 PREPARE 语句因为错误而不能被正确执行。

D: PREPARE stmt_name 的作用域是当前客户端连接会话可见。

E: 要释放一个预定义语句的资源,可以使用 DEALLOCATE PREPARE 句法。

F: EXECUTE stmt_name 句法中,如果 stmt_name 不存在,将会引发一个错误。

G: 如果在终止客户端连接会话时,没有显式地调用 DEALLOCATE PREPARE 句法释放资源,服务器端会自己动释放它。

H: 在预定义语句中,CREATE TABLE, DELETE, DO, INSERT, REPLACE, SELECT, SET, UPDATE, 和大部分的 SHOW 句法被支持。

I: PREPARE 语句不可以用于存储过程,自定义函数!但从 MySQL 5.0.13 开始,它可以被用于存储过程,仍不支持在函数中使用!

下面给个示例:

CREATE PROCEDURE `p1`(IN id INT UNSIGNED,IN name VARCHAR(11))BEGIN lable_exit: 2881064151

BEGIN

SET @SqlCmd = ‘SELECT * FROM tA‘;IF id IS NOT NULL THEN

SET @SqlCmd = CONCAT(@SqlCmd , ‘WHERE id=?‘);PREPARE stmt FROM @SqlCmd;SET @a =id;EXECUTE stmt USING @a;

LEAVE lable_exit;END IF;IF name IS NOT NULL THEN

SET @SqlCmd = CONCAT(@SqlCmd , ‘WHERE name LIKE ?‘);PREPARE stmt FROM @SqlCmd;SET @a = CONCAT(name, ‘%‘);EXECUTE stmt USING @a;

LEAVE lable_exit;END IF;ENDlable_exit;END;

CALL `p1`(1,NULL);

CALL `p1`(NULL,‘QQ‘);DROP PROCEDURE `p1`;

了解了PREPARE的用法,再用变量做表名就很容易了。不过在实际操作过程中还发现其他一些问题,比如变量定义,declare变量和set @var=value变量的用法以及参数传入的变量。

测试后发现,set @var=value这样定义的变量直接写在字符串中就会被当作变量转换,declare的变量和参数传入的变量则必须用CONCAT来连接。具体的原理没有研究。

EXECUTE stmt USING @a;这样的语句USING后面的变量也只能用set @var=value这种,declare和参数传入的变量不行。

另外php调用mysql存储过程的时候也碰到很多问题,总是出现PROCEDURE p can‘t return a result set in the given context这样的问题。

mysql prepare有什么用_mysql中的prepare介绍和应用相关推荐

  1. mysql去除select换行符_MySQL中去除字段中的回车符和换行符

    问题: 在使用[ load data infile 'D:/node.txt' into table node fields terminated by '\t'; ]语句批量导入如下图所示的aaa. ...

  2. mysql的explain怎么看_mysql中explain用法详解

    如果在select语句前放上关键词explain,mysql将解释它如何处理select,提供有关表如何联接和联接的次序. explain的每个输出行提供一个表的相关信息,并且每个行包括下面的列: 1 ...

  3. mysql普通索引自增_mysql中联合索引中的自增列的增长策略

    <深入理解MySQL>中一段介绍MyISAM存储引擎中自动增长列的示例,如下 1 mysql>create table autoincre_demo2 -> (d1 small ...

  4. mysql从表截取信息_mysql中循环截取用户信息并插入到目标表对应的字段中

    操作环境:有表game_list,字段:uid,score1,score2,seat_id,last_update: 传入参数为i_player_detail ,传入的值为多个用户的id.之前分数.之 ...

  5. mysql创建临时表 主键_MySQL中临时表的基本创建与使用教程

    当工作在非常大的表上时,你可能偶尔需要运行很多查询获得一个大量数据的小的子集,不是对整个表运行这些查询,而是让MySQL每次找出所需的少数记录,将记录选择到一个临时表可能更快些,然后在这些表运行查询. ...

  6. mysql 子查询怎么写_MySQL中两种子查询的写法

    MySQL的测试环境 测试表如下 create table test_table2 ( id int auto_increment primary key, pay_id int, pay_time ...

  7. mysql获取当前的月_MYSQL中获取当前的年和月

    展开全部 select year(curdate()),month(curdate()),day(curdate()); select weekofyear(curdate()); 有点细微的差别,w ...

  8. mysql排他锁怎么用_MySQL 中的共享锁和排他锁的用法

    在 MySQL 中的行级锁.表级锁和页级锁中,咱们介绍过,行级锁是 MySQL 中锁定粒度最细的一种锁,行级锁能大大减少数据库操作的冲突.行级锁分为共享锁和排他锁两种,本文将详细介绍共享锁和排他锁的概 ...

  9. mysql日期隐式转换_mysql中的隐式转换

    什么隐式类型转换? 在MySQL中: 当操作符与不同类型的操作数一起使用时,会发生类型转换以使操作数兼容.则会发生转换隐式 也就是说,MySQL会根据需要自动将数字转换为字符串,将字符串转换数字.看到 ...

最新文章

  1. CV_IMAGE_ELEM参数赋值时注意的问题
  2. C++实现简易通讯录
  3. golang import 导入包语法介绍 点 别名 下划线
  4. systemctl介绍
  5. 【BZOJ4818】【SDOI2017】序列计数 [矩阵乘法][DP]
  6. faster_rcnn c++版本的 caffe 封装,动态库(2)
  7. 基于verilog按键消抖设计
  8. 积跬步以至千里_《荀子》名句76则:不积跬步,无以至千里;不积小流,无以成江海...
  9. javamail读取并发送完整的html页面
  10. CRecordset类
  11. python 线性规划问题_使用Python进行线性规划示例
  12. Maven项目环境搭建实例.
  13. java开发利用jacob将word转pdf
  14. 消防工程师 10.2 火灾自动报警系统-设计要求
  15. 通俗易懂的理解BiLSTM-CRF模型中的CRF层
  16. 【JVM · 调优】监控及诊断工具
  17. 计算机word打开,电脑word打不开怎么办
  18. USB 3.0 对无线鼠标的干扰问题
  19. iOS描述文件(.mobileprovision)一键申请
  20. 没有乌云,天就一定晴了么

热门文章

  1. MySQL自连接查询的深入分析
  2. 天下手游服务器维修,《天下》手游3月2日更新公告 亡命副本全服开启
  3. 【Pygame小游戏】剧情流推荐:什么样的游戏剧情能获得大家的喜爱?(决战紫禁之巅 )
  4. 给div元素设置height和overflow:scroll时监听不到滚动事件
  5. 无法安装 64 位版本的 Office
  6. 女友要一个人去厦门旅游
  7. Tomcat相关原理及性能优化
  8. jpg转换成pdf格式在线转换
  9. GF无菌动物实验室设计SICOLAB
  10. 3DCAT实时渲染云在BIM领域的应用