`
hideto
  • 浏览: 2649957 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

在MySQL存储程序里使用SQL

阅读更多
1,使用非SELECT语句
UPDATE/INSERT/SET、DDL、DML等非查询语句可以随意在存储程序里执行
CREATE PROCEDURE simple_sqls()
BEGIN
    DECLARE i INT DEFAULT 1;

    /* Example of a utility statement */
    DROP TABLE IF EXISTS test_table
    CREATE TABLE test_table
        (id INT PRIMARY KEY, some_data VARCHAR(30)) ENGINE=innodb;

    /* Example of an INSERT using a procedure variable */
    WHILE (i<=10) DO
        INSERT INTO TEST_TABLE VALUES(i, CONCAT("record ", i));
        SET i=i+1;
    END WHILE

    /* Example of an UPDATE using procedure variabless */
    SET i =5;
    UPDATE test_table
        SET some_data=CONCAT("I updated row ", i)
    WHERE id=i;

    /* DELETE with a procedure variable */
    DELETE FROM test_table
        WHERE id>i;

END;


2,使用INTO
如果SELECT语句只返回一行记录,则可以使用INTO语句来把结果存入一个变量
如果SELECT语句返回多行记录,则使用INTO会出现运行时错误
CREATE PROCEDURE get_customer_details(in_customer_id INT)
BEGIN
    DECLARE l_customer_name     VARCHAR(30);
    DECLARE l_contact_surname   VARCHAR(30);
    DECLARE l_contact_firstname VARCHAR(30);

    SELECT customer_name, contact_surname, contact_firstname
        INTO l_customer_name, l_contact_surname, contact_firstname
        FROM customers
        WHERE customer_id=in_customer_id;

    /* Do something with the customer record */
END;


3,创建和使用Cursor
可以使用Cursor来处理SELECT语句返回多好记录时的场景
Cursor提供对查询结果集的访问,并且可以循环结果集的每一行,然后每行单独处理
DECLARE l_dept_id BIGINT;
DECLARE c_dept CURSOR FOR
    SELECT department_id FROM departments;

OPEN c_dept;
dept_cursor: LOOP
    FETCH c_dept INTO l_dept_id;
END LOOP dept_cursor;
CLOSE c_dept;

存在的第一个问题:变量声明必须在CURSOR声明之前
存在的第二个问题:上面的程序在FETCH结果集遇到最后一条之后会报错"no data to fetch" error (MySQL error 1329; SQLSTATE 02000)
为了避免第二个问题,我们需要声明一个HANDLER
DECLARE l_dept_id BIGINT;
DECLARE l_last_row_fetched INT;
DECLARE c_dept CURSOR FOR
    SELECT department_id FROM departments;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

SET l_last_row_fetched=0;
OPEN c_dept;
dept_cursor: LOOP
    FETCH c_dept INTO l_dept_id;
    IF l_last_row_fetched=1 THEN
        LEAVE dept_cursor;
    END IF;
END LOOP dept_cursor;
CLOSE c_dept;
SET l_last_row_fetched=0;


4,使用UNBOUNED SELECT语句返回数据给调用者
sp:
CREATE PROCEDCURE sp_get_all_users()
BEGIN
    SELECT user_name, age
        FROM users;
END;

Java客户端:
private void getAllUsers(Connection c) throws SQLException {
    CallableStatement s = c.prepareCall("{CALL sp_get_all_users()}");
    s.execute();
    ResultSet rs = s.getResultSet();
    while(rs.next()) {
        System.out.println(rs.getString("user_name"));
    }
    rs.close();
    s.close();
}


5,使用Prepared Statements处理动态SQL
MySQL支持server-side prepared statements,PREPARE创建,EXECUTE执行,DEALLOCATE销毁:
mysql> PREPARE prod_insert_stmt FROM "INSERT INTO product_codes VALUES(?,?)";
Query OK, 0 rows affected (0.00 sec)
Statement prepared

mysql>
mysql> SET @code='QB';
Query OK, 0 rows affected (0.00 sec)

mysql> SET @name='MySQL Query Browser';
Query OK, 0 rows affected (0.00 sec)

mysql> EXECUTE prod_insert_stmt USING @code,@name;
Query OK, 1 row affected (0.00 sec)

mysql> SET @code='AD';
Query OK, 0 rows affected (0.00 sec)

mysql> SET @name='MySQL Administrator';
Query OK, 0 rows affected (0.02 sec)

mysql> EXECUTE prod_insert_stmt USING @code,@name;
Query OK, 1 row affected (0.00 sec)

mysql> DEALLOCATE PREPARE prod_insert_stmt;
Query OK, 0 rows affected (0.00 sec)

这样一来就可以在sp里做一些手脚,让sp更flexible:
CREATE PROCEDURE set_col_value
    (in_table     VARCHAR(128),
     in_column    VARCHAR(128),
     in_new_value VARCHAR(1000),
     in_where     VARCHAR(4000))

BEGIN
    DECLARE l_sql VARCHAR(4000);
    SET l_slq=CONCAT_ws(' ',
                 'UPDATE', in_table,
                 'SET', in_column, '=', in_new_value,
                 'WHERE', in_where);
    SET @sql=l_sql;
    PREPARE s1 FROM @sql;
    EXECUTE s1;
    DEALLOCATE PREPARE s1;
END;


6,声明HANDLER的语法
DECLARE {CONTINUE | EXIT} HANDLER FOR
    {SQLSTATE sqlstate_code | MySQL error code | condition_name}
    stored_program_statement
分享到:
评论

相关推荐

    MYSQL存储过程编程

    mysql存储过程编程教程:  MySQL 存储过程编程基础 -- 指南,基本语句,存储过程中的 SQL 和错误处理  创建 MySQL 存储过程程序 -- 事务处理,内建函数,存储过程函数和触发器  在应用程序中使用 MySQL 存储...

    基于SQL语言MySQL数据库应用程序及其代码方案

    基于SQL语言MySQL数据库应用程序及其代码方案; MySQL是一种关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司。MySQL是Web应用中使用最广泛的数据库之一,它具有轻量级、快速、稳定和安全的特点。 ...

    MYSQL.rar_SQL分线程_SQL多线程_key5ad_mysql是多线程_replacer4s

    自1996年以来,我们一直都在使用MySQL,其环境有超过 40 个数据库,包含 10,000个表,其中500多个表超过7百万行,这大约有100 个吉字节(GB)的关键应用数据。 MySQL建立的基础是业已用在高要求的生产环境多年的一套...

    mysql存储过程原理与使用方法详解

    本文实例讲述了mysql存储过程原理与使用方法。分享给大家供大家参考,具体如下: 存储过程包含了一系列可执行的sql语句,存储过程存放于MySQL中,通过调用它的名字可以执行其内部的一堆sql 存储过程的优点 #1. 用于...

    使用mss2sql工具将SqlServer转换为Mysql全记录

    今天想用ruby on rails做一个小项目,需要用到mysql数据库,项目中的数据已经有了,只不过是保存在Sql Server中,用rails倒是可以操作Sql Server,但是总感觉不怎么搭配,想转换后使用,网上翻了下,转换的办法有很多,通过...

    基本 MySQL 面试问题,MySQL 是一个开源关系数据库管理系统(RDBMS) 它既可以在网络上运行,也可以在服务器上运行

    MySQL 是一个开源关系数据库管理系统(RDBMS)。...MySQL具有独立的客户端,允许用户使用 SQL 直接与 MySQL 数据库交互,但更常见的是 MySQL 与其他程序一起使用来实现需要关系数据库功能的应用程序。

    mysql安装程序

    文档存储使用单个数据库开发SQL和NoSQL文档应用程序。 新! 事务数据字典实现为一组存储在单个InnoDB表空间中的SQL表。 新! SQL角色用于授予和拒绝用户组的权限,大大减少了安全工作量。 新! 对于更丰富的移动...

    SQLDBX3.6汉化破解版

    SqlDbx是一款非常实用的数据库管理工具,支持SQL的编辑与查询,支持自动语法突显,能够智能化完成操作,内置多种丰富的特色功能。支持的数据源有MSSQL/MYSQL/ODBC/DB2/ASE/SYBASE/ORACLE等数据源。能够同时操作打开...

    MYSQL

    16.3 已知可用 MyODBC一起工作的程序 16.4 怎样填写 ODBC 管理程序的各种域 16.5 怎样在ODBC中获得一个AUTO_INCREMENT列的值 16.6 报告 MyODBC 的问题 17 与一些常用程序一起使用MySQL 17.1...

    mysql8中文参考手册

    Mysql词汇,如何使用MySQL的MySQL客户端程序来创建和使用一个简单的数据库。 备份你的数据库,你可以恢复你的数据,并在问题发生时再运行至关重要,如系统崩溃,硬件故障,或用户误删除数据。备份也基本为维护升级...

    MySQL和SQLServer的比较

    转自: http://www.qqread.com/mysql/z442108305.html 对于程序开发人员而言,目前使用最流行的两种后台数据库即为MySQL和SQLServer。这两者最基本的相似之处在于数据存储和属于查询系统。你可以使用sql来访问这两种...

    SQL.zip_editer_mysql php_sql.stx

    平时比较喜欢用editplus编辑器,用它来写JAVA程序,HTML程序和JSP程序,都很方便,但是最近我处于习惯用editplus来编写SQL存储过程的时候,就觉得很不舒服,主要是它不认SQL关键字,后来我发现这个问题其实是可以...

    MySQL作为一款成熟稳定的数据库管理系统,在数据存储和管理方面具有重要的地位和价值,为各种应用程序提供了可靠的数据支持

    广泛应用:MySQL被广泛用于各种Web应用程序和企业级应用中,如网站数据存储、电子商务系统、日志记录等。许多知名的网站和公司都在使用MySQL作为其后端数据库管理系统。 稳定性和可靠性:MySQL经过长期的发展和改进...

    MySql 5.1 参考手册.chm

    5.12.3. 在多服务器环境中使用客户端程序 5.13. MySQL查询高速缓冲 5.13.1. 查询高速缓冲如何工作 5.13.2. 查询高速缓冲SELECT选项 5.13.3. 查询高速缓冲配置 5.13.4. 查询高速缓冲状态和维护 6. MySQL中的复制 6.1....

    MySQL5.0存储过程

    SQL语句需要先编译然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。...

    MySQL 5.1中文手冊

    5.12.3. 在多服务器环境中使用客户端程序 5.13. MySQL查询高速缓冲 5.13.1. 查询高速缓冲如何工作 5.13.2. 查询高速缓冲SELECT选项 5.13.3. 查询高速缓冲配置 5.13.4. 查询高速缓冲状态和维护 6. MySQL中的复制 6.1....

    MySQL数据库开发教程-基础概念、SQL语法和Node.js操作详解

    - 文件里介绍了MySQL的一些基本概念,如数据库范式、字段约束、函数、事务等。 - 还提供了SQL语句的详细语法,如SELECT、INSERT、UPDATE、DELETE等。 - 最后给出了Node.js操作MySQL数据库的代码示例。 适用人群: ...

    MySQL 5.1参考手册

    5.12.3. 在多服务器环境中使用客户端程序 5.13. MySQL查询高速缓冲 5.13.1. 查询高速缓冲如何工作 5.13.2. 查询高速缓冲SELECT选项 5.13.3. 查询高速缓冲配置 5.13.4. 查询高速缓冲状态和维护 6. MySQL中的复制 6.1....

    MySQL中文参考手册.chm

    1.7 SQL一般信息和教程 1.8 有用的MySQL相关链接 2 MySQL 邮件列表及如何提问或报告错误 2.1 MySQL邮件列表 2.2 提问或报告错误 2.3 怎样报告错误或问题 2.4 在邮件列表上回答...

Global site tag (gtag.js) - Google Analytics