`
jspengxue
  • 浏览: 180970 次
  • 性别: Icon_minigender_1
  • 来自: 天堂和地狱的中间
社区版块
存档分类
最新评论

mysql中存储过程

阅读更多
1.用变量做表名:

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

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

PREPARE stmt_name FROM preparable_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 PREPARE stmt1;

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 * FROM tbl LIMIT ?";
mysql> EXECUTE STMT USING @a;
mysql> SET @skip=1; SET @numrows=5;
mysql> PREPARE STMT FROM "SELECT * FROM tbl 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:
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;
END lable_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这样的问题。

分享到:
评论
1 楼 superherosk123 2008-07-02  
不知道,有没有遇到需要根据表名返回表记录总数的情况(在oracle,mssqlserver 都很容易实现)
翻阅了众多资料都没execute prepareStmt using @var 的返回值的介绍.
很多资料都说mysql 不允许把execute prepareStmt using @var的结果into进某一个变量!
我的解决方案是,将execute prepareStmt 的结果放入一个临时表中,从表中再取数据out之,虽然问题可以解决,但效率是问题!

相关推荐

    mysql调用存储过程

    MySQL存储过程是数据库管理系统中一组为了完成特定功能的SQL语句集,它可以被命名、保存并在需要时调用,极大地提高了数据库开发效率和程序的可维护性。在Java应用程序中,我们经常使用JDBC(Java Database ...

    mysql中存储过程的实例教程

    MySQL存储过程是一种在MySQL数据库中通过定义一系列操作来执行特定任务的程序代码集合。它允许用户封装一系列SQL语句,提高代码的复用性,并且可以通过参数传递,提高数据处理的灵活性。本实例教程将详细介绍如何在...

    mysql存储过程调试工具

    在存储过程中,变量的值可能随着流程的推进而变化,理解这些变化对于找出潜在问题至关重要。"Debugger for MySQL"支持实时查看和跟踪变量值,帮助开发者追踪数据流,定位错误源头。 此外,该工具可能还具备其他辅助...

    MySQL实验报告5(存储过程与函数)(1)(1).pdf

    在存储过程中,使用了“declare exit handler for 1329 set state='error'”语句来处理特定的SQL异常,这里异常代码1329表示尝试访问不存在的游标。当这种异常发生时,将状态变量设置为'error'。利用异常处理机制...

    mysql存储过程教程

    四、存储过程中的控制结构 1. 条件语句:`IF...ELSE`和`CASE`用于实现条件判断。 2. 循环语句:`WHILE`和`REPEAT`用于实现循环操作。 3. 退出语句:`LEAVE`用于跳出循环或整个存储过程。 4. 继续语句:`CONTINUE`...

    MySQL存储过程的异常处理方法

    本实例展示了如何在MySQL存储过程中实现异常处理,以捕获并处理可能出现的错误。 首先,我们注意到在创建存储过程`myProc`时,使用了`delimiter $$`来改变MySQL客户端的语句分隔符,这是为了在存储过程中使用多个...

    mysql经典教程+mysql存储过程讲解

    在存储过程中,还可以使用条件语句(如IF-ELSE)和循环结构(如WHILE或LOOP),使得处理逻辑更加灵活。 接下来,我们讨论触发器。触发器是一种特殊的存储过程,它在特定的数据库事件(如INSERT、UPDATE或DELETE)...

    MySql 分页存储过程以及代码调用

    在这个存储过程中,我们传入了页码(page)、每页大小(pageSize)两个参数,并返回总行数(totalRows)。先计算出起始行号(rowCount),然后执行实际的分页查询。 调用这个存储过程可以使用以下代码: ```sql ...

    mysql存储过程——用于数据库的备份与还原

    5. **错误处理和日志记录**:在存储过程中,应当包含适当的错误处理机制,如`BEGIN...TRY...END TRY...BEGIN CATCH...END CATCH`块,以及日志记录,以便跟踪备份过程的状态和可能出现的问题。 6. **还原数据**:当...

    c++实现调mysql存储过程

    c++实现调mysql存储过程,实现存储过程的出参入参,可以支持查询多数据返回,还有存储过程的复杂数据的增删改等

    Mysql存储过程常用语句模板

    Mysql存储过程常用语句模板(含变量,if,三种循环等等) Mysql存储过程常用语句模板(含变量,if,三种循环等等) Mysql存储过程常用语句模板(含变量,if,三种循环等等) Mysql存储过程常用语句模板(含变量,if,三...

    MySQL创建存储过程批量插入10万条数据

    MySQL创建存储过程批量插入10万条数据 存储过程 1、首先防止主键冲突,我们清空表。 TRUNCATE table A_student; 2、编写存储过程 delimiter ‘$’; CREATE PROCEDURE batchInsert(in args int) BEGIN declare i int ...

    Mysql导出存储过程

    #### 二、MySQL存储过程的基本概念 在了解如何导出存储过程之前,我们先来简要回顾一下存储过程的一些基本概念: - **定义**:存储过程是一组预编译的SQL语句,可以接受输入参数,返回输出参数或结果集,并且可以在...

    MySQL存储过程学习

    MySQL存储过程是数据库管理系统中的一种重要功能,它允许开发者预编译一系列的SQL语句,形成一个可重复使用的代码块,以提高数据处理的效率和应用程序的性能。在这个"MySQL存储过程学习"的主题中,我们将深入探讨...

    Java实现调用MySQL存储过程详解

    总的来说,Java通过JDBC调用MySQL存储过程涉及到连接数据库、创建`CallableStatement`、执行存储过程和处理结果。这使得开发者能够在Java应用中灵活地利用数据库提供的强大功能,实现更高效的数据处理。

    MYSQL分页存储过程

    通过上述示例,我们可以看到,使用MySQL存储过程实现分页查询不仅能够提高查询效率,还能简化应用程序逻辑,增强系统的可维护性和可扩展性。然而,设计存储过程时也需要注意安全性,避免SQL注入等风险,确保数据库...

    MySQL数据库存储过程

    通过阅读这份教程,读者可以学习如何创建、修改、删除存储过程,理解如何在存储过程中使用变量、游标、事务控制,以及如何优化存储过程的性能。 存储过程的使用有助于数据库的安全性,因为它可以限制对数据的直接...

    MySQL 存储过程入门到精通

    MySQL存储过程是数据库管理系统中的一个重要特性,它允许程序员或数据库管理员预先定义一组SQL语句,形成一个可重用的逻辑单元。在这个“MySQL存储过程入门到精通”资料中,你将深入理解存储过程的原理、创建、调用...

    MySQL存储过程编程.pdf

    MySQL 存储过程编程是指在 MySQL 数据库中使用存储过程来实现业务逻辑的编程技术。存储过程是一种可以在数据库中存储和执行的程序单元,它可以实现复杂的业务逻辑和数据处理操作。 在 MySQL 5.0 中,存储过程的...

    mysql中文手册+mysql命令大全+mysql存储过程

    最后,"mysql存储过程.pdf"专注于MySQL的存储过程。存储过程是预编译的SQL语句集合,可以提高数据库操作的性能,减少网络流量,并增强数据安全。在PDF文档中,你将学习如何定义、调用和管理存储过程,以及如何使用...

Global site tag (gtag.js) - Google Analytics