澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

澳门新萄京官方网站:至于Mysql存款和储蓄进程及

2019-09-22 作者:数据库网络   |   浏览(106)

MySQL5 中添加了存储过程的支持。

MY SQL存储过程、游标、触发器,sql存储过程

MySQL5 中添加了存储过程的支持。

 大多数SQL语句都是针对一个或多个表的单条语句。并非所有的操作都怎么简单。经常会有一个完整的操作需要多条才能完成

 存储过程简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合。可将其视为批文件。虽然他们的作用不仅限于批处理。

 为什么要使用存储过程:优点

1 通过吧处理封装在容易使用的单元中,简化复杂的操作

2 由于不要求反复建立一系列处理步骤,这保证了数据的完整性。如果开发人员和应用程序都使用了同一存储过程,则所使用的代码是相同的。还有就是防止错误,需要执行的步骤越多,出错的可能性越大。防止错误保证了数据的一致性。

3 简化对变动的管理。如果表名、列名或业务逻辑有变化。只需要更改存储过程的代码,使用它的人员不会改自己的代码了都。

4 提高性能,因为使用存储过程比使用单条SQL语句要快

5 存在一些职能用在单个请求中的MySQL元素和特性,存储过程可以使用它们来编写功能更强更灵活的代码

换句话说3个主要好处简单、安全、高性能

    缺点:

 1 一般来说,存储过程的编写要比基本的SQL语句复杂,编写存储过程需要更高的技能,更丰富的经验。

 2 你可能没有创建存储过程的安全访问权限。许多数据库管理员限制存储过程的创建,允许用户使用存储过程,但不允许创建存储过程

    存储过程是非常有用的,应该尽可能的使用它们

    执行存储过程

        MySQL称存储过程的执行为调用,因此MySQL执行存储过程的语句为CALL        .CALL接受存储过程的名字以及需要传递给它的任意参数

            CALL productpricing(@pricelow , @pricehigh , @priceaverage);

            //执行名为productpricing的存储过程,它计算并返回产品的最低、最高和平均价格

    创建存储过程

        CREATE  PROCEDURE 存储过程名()

           一个例子说明:一个返回产品平均价格的存储过程如下代码:

           CREATE  PROCEDURE  productpricing()

           BEGIN

            SELECT Avg(prod_price)  AS priceaverage

           FROM products;

           END;

        //创建存储过程名为productpricing,如果存储过程需要接受参数,可以在()中列举出来。即使没有参数后面仍然要跟()。BEGIN和END语句用来限定存储过程体,过程体本身是个简单的SELECT语句

        在MYSQL处理这段代码时会创建一个新的存储过程productpricing。没有返回数据。因为这段代码时创建而不是使用存储过程。

 

    Mysql命令行客户机的分隔符

        默认的MySQL语句分隔符为分号 ; 。Mysql命令行实用程序也是 ; 作为语句分隔符。如果命令行实用程序要解释存储过程自身的 ; 字符,则他们最终不会成为存储过程的成分,这会使存储过程中的SQL出现句法错误

        解决方法是临时更改命令实用程序的语句分隔符

            DELIMITER //    //定义新的语句分隔符为//

            CREATE PROCEDURE productpricing()

            BEGIN

            SELECT Avg(prod_price) AS priceaverage

            FROM products;

            END //

            DELIMITER ;    //改回原来的语句分隔符为 ;

            除符号外,任何字符都可以作为语句分隔符

        CALL productpricing();  //使用productpricing存储过程

        执行刚创建的存储过程并显示返回的结果。因为存储过程实际上是一种函数,所以存储过程名后面要有()符号

    删除存储过程

        DROP PROCEDURE productpricing ;     //删除存储过程后面不需要跟(),只给出存储过程名

        为了删除存储过程不存在时删除产生错误,可以判断仅存储过程存在时删除

        DROP PROCEDURE IF EXISTS

        使用参数

        Productpricing只是一个简单的存储过程,他简单地显示SELECT语句的结果。

        一般存储过程并不显示结果,而是把结果返回给你指定的变量

            CREATE PROCEDURE productpricing(

            OUT p1 DECIMAL(8,2),

            OUT ph DECIMAL(8,2),

            OUT pa DECIMAL(8,2),

            )

            BEGIN

            SELECT Min(prod_price)

            INTO p1

            FROM products;

            SELECT Max(prod_price)

            INTO ph

            FROM products;

            SELECT Avg(prod_price)

            INTO pa

            FROM products;

            END;

            此存储过程接受3个参数,p1存储产品最低价格,ph存储产品最高价格,pa存储产品平均价格。每个参数必须指定类型,这里使用十进制值。关键字OUT指出相应的参数用来从存储过程传给一个值(返回给调用者)。MySQL支持IN(传递给存储过程)、OUT(从存储过程中传出、如这里所用)和INOUT(对存储过程传入和传出)类型的参数。存储过程的代码位于BEGIN和END语句内,如前所见,它们是一些列SELECT语句,用来检索值,然后保存到相应的变量(通过INTO关键字)

        调用修改过的存储过程必须指定3个变量名:

        CALL productpricing(@pricelow , @pricehigh , @priceaverage);

        这条CALL语句给出3个参数,它们是存储过程将保存结果的3个变量的名字

    变量名  所有的MySQL变量都必须以@开始

    使用变量

        SELECT @priceaverage ;

        SELECT @pricelow , @pricehigh , @priceaverage ;   //获得3给变量的值

        下面是另一个例子,这次使用IN和OUT参数。ordertotal接受订单号,并返回该订单的合计

            CREATE PROCEDURE ordertotal(

           IN onumber INT,

           OUT ototal DECIMAL(8,2)

            )

            BEGIN

            SELECT Sum(item_price*quantity)

            FROM orderitems

            WHERE order_num = onumber

            INTO ototal;

            END;

            //onumber定义为IN,因为订单号时被传入存储过程,ototal定义为OUT,因为要从存储过程中返回合计,SELECT语句使用这两个参数,WHERE子句使用onumber选择正确的行,INTO使用ototal存储计算出来的合计

    为了调用这个新的过程,可以使用下列语句:

        CALL ordertotal(2005 , @total);   //这样查询其他的订单总计可直接改变订单号即可

        SELECT @total;

    建立智能的存储过程

        上面的存储过程基本都是封装MySQL简单的SELECT语句,但存储过程的威力在它包含业务逻辑和智能处理时才显示出来

        例如:你需要和以前一样的订单合计,但需要对合计增加营业税,不活只针对某些顾客(或许是你所在区的顾客)。那么需要做下面的事情:

            1 获得合计(与以前一样)

            2 吧营业税有条件地添加到合计

            3 返回合计(带或不带税)

        存储过程的完整工作如下:

            -- Name: ordertotal

            -- Parameters: onumber = 订单号

            --           taxable = 1为有营业税 0 为没有

            --           ototal = 合计

            CREATE  PROCEDURE ordertotal(

            IN onumber INT,

            IN taxable BOOLEAN,

            OUT ototal DECIMAL(8,2)

            -- COMMENT()中的内容将在SHOW PROCEDURE STATUS ordertotal()中显示,其备注作用

            ) COMMENT 'Obtain order total , optionally adding tax'

            BEGIN

            -- 定义total局部变量

            DECLARE total DECIMAL(8,2)

            DECLARE taxrate INT DEFAULT 6;

 

            -- 获得订单的合计,并将结果存储到局部变量total中

            SELECT Sum(item_price*quantity)

            FROM orderitems

            WHERE order_num = onumber

            INTO total;

 

            -- 判断是否需要增加营业税,如为真,这增加6%的营业税

            IF taxable THEN

            SELECT total (total/100*taxrate) INTO total;

                  END IF;

            -- 把局部变量total中才合计传给ototal中

            SELECT total INTO ototal;

            END;

            此存储过程有很大的变动,首先,增加了注释(前面放置--)。在存储过程复杂性增加时,这样很重要。在存储体中,用DECLARE语句定义了两个局部变量。DECLARE要求制定变量名和数据类型,它也支持可选的默认值(这个例子中taxrate的默认设置为6%),SELECT 语句已经改变,因此其结果存储到total局部变量中而不是ototal。IF语句检查taxable是否为真,如果为真,则用另一SELECT语句增加营业税到局部变量total,最后用另一SELECT语句将total(增加了或没有增加的)保存到ototal中。

    COMMENT关键字  本列中的存储过程在CREATE PROCEDURE 语句中包含了一个COMMENT值,他不是必需的,但如果给出,将在SHOW PROCEDURE STATUS的结果中显示

    IF语句   这个例子中给出了MySQL的IF语句的基本用法。IF语句还支持ELSEIF和ELSE子句(前者还使用THEN子句,后者不使用)

    检查存储过程

        为显示用来创建一个存储过程的CREATE语句,使用SHOW CREATE PROCEDURE语句

            SHOW CREATE PROCEDURE ordertotal;

        为了获得包括何时、有谁创建等详细信息的存储过程列表。使用SHOW PROCEDURE STATUS.限制过程状态结果,为了限制其输出,可以使用LIKE指定一个过滤模式,例如:SHOW PROCEDURE STATUS LIKE ''ordertotal;

MySQL5添加了对游标的支持

    只能用于存储过程

    由前几章可知,mysql检索操作返回一组称为结果集的行。都与mysql语句匹配的行(0行或多行),使用简单的SELECT语句,没有办法得到第一行、下一行或前10行,也不存在每次行地处理所有行的简单方法(相对于成批处理他们)

    有时,需要在检索出来的行中前进或后退一行或多行。这就是使用游标的原因。游标(cursor)是一个存储在MYSQL服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。

    游标主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或做出更改。

    使用游标

        使用游标涉及几个明确的步骤:

            1 在能够使用游标前,必须声明(定义)它,这个过程实际上没有检索数据,它只是定义要使用的SELECT语句

            2 一旦声明后,必须打开游标以供使用。这个过程用钱吗定义的SELECT语句吧数据实际检索出来

            3 对于填有数据的游标,根据需要取出(检索)的各行

            4 在接受游标使用时,必须关闭它 如果不明确关闭游标,MySQL将会在到达END语句时自动关闭它

    创建游标

        游标可用DECLARE 语句创建。 DECLARE命名游标,并定义相应的SELECT语句。根据需要选择带有WHERE和其他子句。如:下面第一名为ordernumbers的游标,使用了检索所有订单的SELECT语句

            CREATE PROCEDURE processorders()

            BEGIN

            DECLARE ordernumbers CURSOR

            FOR

            SELECT order_num FROM orders ;

            END;

            存储过程处理完成后,游标就消失,因为它局限于存储过程

    打开和关闭游标

            CREATE PROCEDURE processorders()

            BEGIN

            DECLAREordernumbers CURSOR

            FOR

            SELECT order_num FROM orders ;

            Open ordernumbers ;

            Close ordernumbers ;  //CLOSE释放游标使用的所有内部内存和资源,因此,每个游标不需要时都应该关闭

            END;

    使用游标数据

        在一个游标被打开后,可以使用FETCH语句分别访问它的每一行。FETCH指定检索什么数据(所需的要列),检索出来的数据存储在什么地方。它还向前移动游标中的内部行指针,使下一条FETCH语句检索下一行,相当于PHP中的each()函数

循环检索数据,从第一行到最后一行

            CREATE PROCEDURE processorders()

            BEGIN

            -- 声明局部变量

            DECLARE done BOOLEAN DEFAULT 0;

            DECLARE o INT;

 

            DECLAREordernumbers CURSOR

            FOR

            SELECT order_num FROM orders ;

            -- 当SQLSTATE为02000时设置done值为1

            DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

            --打开游标

            Open ordernumbers ;

            -- 开始循环

            REPEAT

            -- 把当前行的值赋给声明的局部变量o中

            FETCH ordernumbers INTO o;

            -- 当done为真时停止循环

            UNTIL done END REPEAT;

            --关闭游标

            Close ordernumbers ;  //CLOSE释放游标使用的所有内部内存和资源,因此,每个游标不需要时都应该关闭

            END;

        语句中定义了CONTINUE HANDLER ,它是在条件出现时被执行的代码。这里,它指出当SQLSTATE '02000'出现时,SET done=1。SQLSTATE '02000'是一个未找到条件,当REPEAT没有更多的行供循环时,出现这个条件。

    DECLARE 语句次序  用DECLARE语句定义局部变量必须在定义任意游标或句柄之前定义,而句柄必须在游标之后定义。不遵守此规则就会出错

重复和循环   除这里使用REPEAT语句外,MySQL还支持循环语句,它可用来重复执行代码,直到使用LEAVE语句手动退出为止。通常REPEAT语句的语法使它更适合于对游标进行的循环。

为了把这些内容组织起来,这次吧取出的数据进行某种实际的处理

        CREATE PROCEDURE processorders()

        BEGIN

        -- 声明局部变量

        DECLARE done BOOLEAN DEFAULT 0;

        DECLARE o INT;

        DECLARE t DECIMAL(8,2)

 

        DECLAREordernumbers CURSOR

        FOR

        SELECT order_num FROM orders ;

        -- 当SQLSTATE为02000时设置done值为1

        DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

        -- 创建一个ordertotals的表

        CREATE TABLE IF NOT EXISTS ordertotals( order_num INT , total DECIMAL(8,2))

        --打开游标

        Open ordernumbers ;

        -- 开始循环

        REPEAT

        -- 把当前行的值赋给声明的局部变量o中

        FETCH ordernumbers INTO o;

        -- 用上文讲到的ordertotal存储过程并传入参数,返回营业税计算后的合计传给t变量

        CALL ordertotal(o , 1 ,t)

        -- 把订单号和合计插入到新建的ordertotals表中

        INSERT INTO ordertotals(order_num, total) VALUES(o , t);

        -- 当done为真时停止循环

        UNTIL done END REPEAT;

        --关闭游标

        Close ordernumbers ;  //CLOSE释放游标使用的所有内部内存和资源,因此,每个游标不需要时都应该关闭

        END;

        最后SELECT * FROM ordertotals就能查看结果了

 使用触发器

    MySQL5版本后支持触发器

    只有表支持触发器,视图不支持触发器

    MySQL语句在需要的时被执行,存储过程也是如此,但是如果你想要某条语句(或某些语句)在事件发生时自动执行,那该怎么办呢:例如:

        1 每增加一个顾客到某个数据库表时,都检查其电话号码格式是否正确,区的缩写是否为大写

        2 每当订购一个产品时,都从库存数量中减少订购的数量

        3 无论何时删除一行,都在某个存档中保留一个副本

    这写例子的共同之处是他们都需要在某个表发生更改时自动处理。这就是触发器。触发器是MySQL响应一下任意语句而自动执行的一条MySQL语句(或位于BEGIN和END语句之间的一组语句)

    1 DELETE

    2 INSERT

    3 UPDATE

    其他的MySQL语句不支持触发器

    创建触发器

        创建触发器需要给出4条信息

        1 唯一的触发器名;  //保存每个数据库中的触发器名唯一

        2 触发器关联的表;

        3 触发器应该响应的活动(DELETE、INSERT或UPDATE)

        4 触发器何时执行(处理前还是后,前是BEFORE 后是AFTER)

        创建触发器用CREATE TRIGGER

        CREATE TRIGGER newproduct AFTER INSERT ON products

        FOR EACH ROW SELECT'Product added'

       创建新触发器newproduct ,它将在INSERT语句成功执行后执行。这个触发器还镇定FOR EACH ROW,因此代码对每个插入的行执行。这个例子作用是文本对每个插入的行显示一次product added

        FOR EACH ROW 针对每个行都有作用,避免了INSERT一次插入多条语句

    触发器定义规则

        触发器按每个表每个事件每次地定义,每个表每个事件每次只允许定义一个触发器,因此,每个表最多定义6个触发器(每条INSERT UPDATE 和DELETE的之前和之后)。单个触发器不能与多个事件或多个表关联,所以,如果你需要一个对INSERT 和UPDATE存储执行的触发器,则应该定义两个触发器

    触发器失败  如果BEFORE(之前)触发器失败,则MySQL将不执行SQL语句的请求操作,此外,如果BEFORE触发器或语句本身失败,MySQL将不执行AFTER(之后)触发器

    删除触发器

        DROP TRIGGER newproduct;

        触发器不能更新或覆盖,所以修改触发器只能先删除再创建

    使用触发器

        我们来看看每种触发器以及它们的差别

澳门新萄京官方网站:至于Mysql存款和储蓄进程及游标的表达书,存款和储蓄进度。    INSERT 触发器

        INSERT触发器在INSERT语句执行之前或之后执行。需要知道以下几点:

    1 在INSERT触发器代码内,可引用一个名为NEW的虚拟表,访问被插入的行

    2 在BEFORE INSERT触发器中,NEW中的值也可以被更新(允许更改插入的值)

    3 对于AUTO_INCREMENT列,NEW在INSERT执行之前包含0,在INSERT执行之后包含新的自动生成值

        提示:通常BEFORE用于数据验证和净化(目的是保证插入表中的数据确实是需要的数据)。本提示也适用于UPDATE触发器

    DELETE 触发器

        DELETE触发器在语句执行之前还是之后执行,需要知道以下几点:

    1 在DELETE触发器代码内,你可以引用一个名为OLD的虚拟表,访问被删除的行;

    2 OLD中的值全部是只读的,不能更新

        例子演示适用OLD保存将要除的行到一个存档表中

        CREATE TRIGGERdeleteorder BEFORE DELETE ON orders

        FOR EACH ROW

        BEGIN  

        INSERT INTO archive_orders(order_num , order_date , cust_id)

        VALUES(OLD.order_num , OLD.order_date , OLD.cust_id);

        END;

        //此处的BEGIN  END块是非必需的,可以没有

    在任何订单删除之前执行这个触发器,它适用一条INSERT语句将OLD中的值(将要删除的值)保存到一个名为archive_orders的存档表中

    BEFORE DELETE触发器的优点是(相对于AFTER DELETE触发器),如果由于某种原因,订单不能被存档,DELETE本身将被放弃执行。

    多语言触发器  正如上面所见,触发器deleteorder 使用了BEGIN和END语句标记触发器体。这在此例中并不是必需的,不过也没有害处。使用BEGIN  END块的好处是触发器能容纳多条SQL语句。

    UPDATE触发器

        UPDATE触发器在语句执行之前还是之后执行,需要知道以下几点:

        1 在UPDATE触发器代码中,你可以引用一个名为OLD的虚拟表访问(UPDATE语句前)的值,引用一名为NEW的虚拟表访问新更新的值

        2 在BEFORE UPDATE触发器中,NEW中的值可能被更新,(允许更改将要用于UPDATE语句中的值)

        3 OLD中的值全都是只读的,不能更新

            例子:保证州名的缩写总是大写(不管UPDATE语句给出的是大写还是小写)

            CREATE TRIGGER updatevendor BEFORE UPDATE ON vendores FOR EACH ROW SETNEW.vend_state = Upper(NEW.vend_state)

    触发器的进一步介绍

    1 与其他DBMS相比,MySQL5中支持的触发器相当初级。以后可能会增强

    2 创建触发器可能需要特殊的安全访问权限,但是触发器的执行时自动的.如果INSERT UPDATE DELETE能执行,触发器就能执行

    3 应该用触发器来保证数据的一致性(大小写、格式等)。在触发器中执行这种类型的处理的优点是它总是进行这个处理,而且是透明地进行,与客户机应用无关

    4 触发器的一种非常有意义的使用创建审计跟踪。使用触发器把更改(如果需要,甚至还有之前和之后的状态)记录到另一表非常容易

    5 遗憾的是,MySQL触发器中不支持CALL语句,这表示不能从触发器中调用存储过程。所需要的存储过程代码需要复制到触发器内

 

 

SQL存储过程、游标、触发器,sql存储过程 MySQL5 中添加了存储过程的支持。 大多数 SQL语句都是针对一个或多个表的单条语句。并非所有的...

21.创建和操作表

    我和mysql存储过程、游标犹如“形同陌路”,不得不记录以便以后查看。

 大多数SQL语句都是针对一个或多个表的单条语句。并非所有的操作都怎么简单。经常会有一个完整的操作需要多条才能完成

21.1.创建表

本文是阅读《mysql必知必会》的读书笔记,仅供参考:

 存储过程简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合。可将其视为批文件。虽然他们的作用不仅限于批处理。

CREATE TABLE创建表,必须给出下列信息:

1、CALL调用存储过程,后接存储过程名及所需参数。如:

 为什么要使用存储过程:优点

1) 新表的名字,在关键字CREATETABLE之后

    CALL ordertotal(20005, 1, @total);

1 通过吧处理封装在容易使用的单元中,简化复杂的操作

2) 表列的名字和定义,用逗号分隔

    SELECT @total;

2 由于不要求反复建立一系列处理步骤,这保证了数据的完整性。如果开发人员和应用程序都使用了同一存储过程,则所使用的代码是相同的。还有就是防止错误,需要执行的步骤越多,出错的可能性越大。防止错误保证了数据的一致性。

CREATE TABLE customers

2、创建存储过程(应用程序中):

3 简化对变动的管理。如果表名、列名或业务逻辑有变化。只需要更改存储过程的代码,使用它的人员不会改自己的代码了都。

(

    DELIMITER //    #告诉命令行程序使用//做结束分割符,默认使用;做结束分割符

4 提高性能,因为使用存储过程比使用单条SQL语句要快

cust_id int NOT NULL AUTO_INCREMENT,

    CREATE PROCEDURE productpricing(#创建存储过程

5 存在一些职能用在单个请求中的MySQL元素和特性,存储过程可以使用它们来编写功能更强更灵活的代码

cust_name char(50) NOTNULL,

    IN onumber INT,    # IN表示传递给存储过程

换句话说3个主要好处简单、安全、高性能

cust_address char(50) NULL,

    IN taxable BOOLEAN,     # 数据类型和定义表结构数据类型相同

    缺点:

cust_city char(50) NULL,

    OUT ototal DECIMAL(8,2)    # OUT表示传出结果(调用存储过程后,可以通过SELECT查询),INOUT表示既传入到存储过程也传出到结果

 1 一般来说,存储过程的编写要比基本的SQL语句复杂,编写存储过程需要更高的技能,更丰富的经验。

cust_state char(5) NULL,

) COMMENT 'Obtain order total, optionally adding tax'    # COMMENT结果将在SHOW PROCEDURE STATUS(显示存储过程详细内容)中显示

 2 你可能没有创建存储过程的安全访问权限。许多数据库管理员限制存储过程的创建,允许用户使用存储过程,但不允许创建存储过程

cust_zip char(10) NULL,

    BEGIN    # 标识存储过程开始

    存储过程是非常有用的,应该尽可能的使用它们

cust_country char(50) NULL,

    -- Declare variable for total    # “-- 。。。”也表示注释

    执行存储过程

cust_contact char(50) NULL,

    DECLARE total DECIMAL(8,2);

        MySQL称存储过程的执行为调用,因此MySQL执行存储过程的语句为CALL        .CALL接受存储过程的名字以及需要传递给它的任意参数

cust_email char(255) NULL,

    -- Declare tax percentage

            CALL productpricing(@pricelow , @pricehigh , @priceaverage);

primaryKEY (cust_id)

    DECLARE taxrate INT DEFAULT 6;

            //执行名为productpricing的存储过程,它计算并返回产品的最低、最高和平均价格

) ENGINE = InnoDB;

    -- Get the order total    

    创建存储过程

有以下几点需要注意:

    SELECT Sum(item_price*quantity)

澳门新萄京官方网站:至于Mysql存款和储蓄进程及游标的表达书,存款和储蓄进度。        CREATE  PROCEDURE 存储过程名()

1)其中主键也可以用多个列组成,如orderitems表中在主键表示如下:

    FROM orderitems

           一个例子说明:一个返回产品平均价格的存储过程如下代码:

PRIMARY KEY(order_num,order_item)

    WHERE order_num = onumber

           CREATE  PROCEDURE  productpricing()

主键只能使用不允许NULL值的列。

    INTO total;    # INTO将查询结果赋值到total

           BEGIN

2)每个表只允许一个AUTO_INCREMENT列。可用SELECTlast_insert_id()获取最后一个AUTO_INCREMENT值。

    -- Is this taxable

            SELECT Avg(prod_price)  AS priceaverage

3)用DEFAULT指定默认值

    IF taxable THEN    # IF语句开始,还有ELSEIF(配合THEN使用)、ELSE(不使用THEN)

           FROM products;

4)引擎类型

    -- Yes, so add taxrate to the total

           END;

InnoDB是一个可靠的事物处理引擎,它不支持全文本搜索

    SELECT total (total/100*taxrate) INTO total;

        //创建存储过程名为productpricing,如果存储过程需要接受参数,可以在()中列举出来。即使没有参数后面仍然要跟()。BEGIN和END语句用来限定存储过程体,过程体本身是个简单的SELECT语句

MEMORY在功能上等同于MyISAM,但由于数据存储在内存中,速度很快(特适合于临时表)

    END IF;    # IF语句结束

        在MYSQL处理这段代码时会创建一个新的存储过程productpricing。没有返回数据。因为这段代码时创建而不是使用存储过程。

MyISAM是一个性能极高的引擎,它支持全文本搜索,但不支持事物处理

    -- And finally, save to out variable

 

引擎可以混用,但外键不能夸引擎。

    SELECT total INTO ototal;

    Mysql命令行客户机的分隔符

21.2更新表

    END //    # 标识存储过程结束,并使用//做语句结束

        默认的MySQL语句分隔符为分号 ; 。Mysql命令行实用程序也是 ; 作为语句分隔符。如果命令行实用程序要解释存储过程自身的 ; 字符,则他们最终不会成为存储过程的成分,这会使存储过程中的SQL出现句法错误

必须提供以下信息:

    DELIMITER ;    # 恢复原语句分割符

        解决方法是临时更改命令实用程序的语句分隔符

1)在ALTER TABLE之后给出要更改的表名

3、查看存储过程:

            DELIMITER //    //定义新的语句分隔符为//

2)所做更改的列表

    SHOW CREATE PROCEDURE 存储过程名    # 查看存储过程

            CREATE PROCEDURE productpricing()

ALTER TABLE vendors ADD vend_phoneCHAR(20);//增加一个新列

    SHOW PROCEDURE STATUS LIKE 'ordertotal';    # 查看存储过程详细信息(何时、由谁创建等详细信息),可以使用过滤条件

            BEGIN

ALTER TABLE vendors DROP vend_phone;//删除一个列

4、使用游标:

            SELECT Avg(prod_price) AS priceaverage

定义外键:

    CREATE PROCEDURE processorders()

            FROM products;

ALTER TABLE orderitems ADD CONSTRAINTfk_orderitems_orders FOREIGN KEY (order_num) REFERENCE orders(order_num);

    BEGIN

            END //

21.3删除表

    # 声明规则:变量声明在游标声明之前,CONTINUE HANDLER声明在游标声明之后

            DELIMITER ;    //改回原来的语句分隔符为 ;

DROP TABLE customers;

    -- Declare local variables

            除符号外,任何字符都可以作为语句分隔符

21.4重命名表

    DECLARE done BOOLEAN DEFAULT 0;    # 声明结束标识符

        CALL productpricing();  //使用productpricing存储过程

RENAME TABLE backup_customers TO customers;

    DECLARE o INT;

        执行刚创建的存储过程并显示返回的结果。因为存储过程实际上是一种函数,所以存储过程名后面要有()符号

22.使用视图

    DECLARE t DECIMAL(8,2);

    删除存储过程

视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。

    -- Declare the cursor

        DROP PROCEDURE productpricing ;     //删除存储过程后面不需要跟(),只给出存储过程名

视图不包含表中应该有的任何列或数据,它包含的是一个SQL查询。视图仅仅用来查看存储在别处数据的一种设施。视图本身不包含数据,因此它们返回的数据是从其他表中检索出来的。在添加或更改这些彪中国的数据时,视图将返回改变过的数据。每次使用视图时,都必须处理查询执行时所需要的任一检索。

    DECLARE ordernumbers CURSOR    # 声明游标,CURSOR表示游标,声明游标后必须打开使用,打开之后执行游标的SELECT操作,声明的时候不执行

        为了删除存储过程不存在时删除产生错误,可以判断仅存储过程存在时删除

视图不能索引,也不能有关联的触发器或默认值。

    FOR

        DROP PROCEDURE IF EXISTS

使用视图:

    SELECT order_num FROM orders;

        使用参数

1)视图用CREATE VIEW来创建

    -- Declare continue handler

        Productpricing只是一个简单的存储过程,他简单地显示SELECT语句的结果。

2)使用SHOW CREATE VIEWviewname;来查看创建视图的语句

    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;        #CONTINUE HANDLER表示当达到一定条件后执行,SQLSTATE '02000'表示未找到下一行,达到一定条件执行的语句

        一般存储过程并不显示结果,而是把结果返回给你指定的变量

3)用DROP删除视图,其语法为DROPVIEW viewname;

    -- Create a table to store the results

            CREATE PROCEDURE productpricing(

4) 更新视图时,可以先用DROP再用CREATE,也可以直接用CREATEOR REPLACE VIEW。

    CREATE TABLE IF NOT EXISTS ordertotals    # 不存在则创建表

            OUT p1 DECIMAL(8,2),

22.1利用视图简化复杂的联结

    (order_num INT, total DECIMAL(8,2));

       澳门新萄京官方网站,     OUT ph DECIMAL(8,2),

mysql> CREATE VIEW productcustomers ASSELECT cust_name,cust_contact,prod_id FRO

    -- Open the cursor

            OUT pa DECIMAL(8,2),

M customers,orders,orderitems WHEREcustomers.cust_id = orders.cust_id AND order

    OPEN ordernumbers;    # 打开游标

            )

items.order_num = orders.order_num;

    -- Loop through all rows

            BEGIN

Query OK, 0 rows affected (0.13 sec)

    REPEAT    # 循环游标

            SELECT Min(prod_price)

为检索订购产品TNT2的客户,可如下执行:

    -- Get order number

            INTO p1

mysql> SELECT cust_name,cust_contactFROM productcustomers WHERE prod_id = 'TNT2

    FETCH ordernumbers INTO o;    # FETCH表示每一个游标结果

            FROM products;

';

    -- Get the total for this order

            SELECT Max(prod_price)

---------------- --------------

    CALL ordertotal(o, 1, t);    # 调用存储过程

            INTO ph

| cust_name | cust_contact |

    -- Insert order and total into ordertotals

            FROM products;

---------------- --------------

    INSERT INTO ordertotals(order_num, total)

            SELECT Avg(prod_price)

| Coyote Inc. | YLee |

    VALUES(o, t);    # 执行插入语句

            INTO pa

| Yosemite Place | Y Sam |

    -- End of loop

            FROM products;

---------------- --------------

    UNTIL done END REPEAT;    # UNTIL表示达到一定条件后执行,END REPEAT表示结束循环

            END;

2 rows in set (0.00 sec)

    -- Close the cursor

            此存储过程接受3个参数,p1存储产品最低价格,ph存储产品最高价格,pa存储产品平均价格。每个参数必须指定类型,这里使用十进制值。关键字OUT指出相应的参数用来从存储过程传给一个值(返回给调用者)。MySQL支持IN(传递给存储过程)、OUT(从存储过程中传出、如这里所用)和INOUT(对存储过程传入和传出)类型的参数。存储过程的代码位于BEGIN和END语句内,如前所见,它们是一些列SELECT语句,用来检索值,然后保存到相应的变量(通过INTO关键字)

22.2用视图重新格式化检索出的数据

    CLOSE ordernumbers;    # 关闭游标,如果没有关闭游标则在存储过程结束后自动关闭游标,游标只能应用到当前存储过程中

        调用修改过的存储过程必须指定3个变量名:

SELECT * FROM productcustomers;

    END;

        CALL productpricing(@pricelow , @pricehigh , @priceaverage);

22.2视图的更新

        这条CALL语句给出3个参数,它们是存储过程将保存结果的3个变量的名字

有时,视图是可更新的(即可以对它们使用INSERT、UPDATE和DELETE),对视图增加或删除行,实际上是对其基表增加或删除行。

    变量名  所有的MySQL变量都必须以@开始

但是,如果视图定义中有以下操作,则不能进行更新:

    使用变量

1) 分组(使用GROUP BY和HAVING)

        SELECT @priceaverage ;

2) 联结

        SELECT @pricelow , @pricehigh , @priceaverage ;   //获得3给变量的值

3) 子查询

        下面是另一个例子,这次使用IN和OUT参数。ordertotal接受订单号,并返回该订单的合计

4) 并

            CREATE PROCEDURE ordertotal(

5) 聚集函数

           IN onumber INT,

6) DISTINCT

           OUT ototal DECIMAL(8,2)

7) 导出(计算)列

            )

23.使用存储过程

            BEGIN

存储过程简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合。可将其视为批文件,虽然它们的作用不仅限于批处理。

            SELECT Sum(item_price*quantity)

存储过程有3个主要的好处:简单、安全、高性能。

            FROM orderitems

23.1执行存储过程

            WHERE order_num = onumber

MySQL称存储过程的执行为调用,因此MySQL执行存储过程的语句为CALL。CALL接受存储过程的名字以及需要传递给它的任意参数。

            INTO ototal;

CALL producpricing(@pricelow,@pricehigh,priceaverage);

            END;

其中,执行名为productpricing的存储过程,它计算并返回产品的最低、最高和平均价格。存储过程可以显示结果,也可以不显示结果。

            //onumber定义为IN,因为订单号时被传入存储过程,ototal定义为OUT,因为要从存储过程中返回合计,SELECT语句使用这两个参数,WHERE子句使用onumber选择正确的行,INTO使用ototal存储计算出来的合计

23.2创建过程

    为了调用这个新的过程,可以使用下列语句:

CREATE PROCEDURE productpricing()

        CALL ordertotal(2005 , @total);   //这样查询其他的订单总计可直接改变订单号即可

BEGIN

        SELECT @total;

SELECTAve(prod_price) AS priceaverage

    建立智能的存储过程

FROMproducts;

        上面的存储过程基本都是封装MySQL简单的SELECT语句,但存储过程的威力在它包含业务逻辑和智能处理时才显示出来

END;

        例如:你需要和以前一样的订单合计,但需要对合计增加营业税,不活只针对某些顾客(或许是你所在区的顾客)。那么需要做下面的事情:

此存储过程名为productricing,用CREATE PROCEDURE productpricing()语句定义。如果存储过程接受参数,它们将在()中列举出来。此存储过程没有参数,但后跟的()仍然需要。BEGIN和END语句用来限定存储过程体,过程体本事仅是一个简单的SELECT语句。

            1 获得合计(与以前一样)

在MySQL处理这段代码时,它创建一个新的存储过程productpricing。没有返回数据,因为这段代码并未调用存储过程,这里只是为以后使用而创建它。

            2 吧营业税有条件地添加到合计

如果使用MySQL命令行使用程序,由于默认的MySQL语句结束符为;,则存储体内的;字符将不会最终成为储存过程的成分,这会导致语法错误。解决办法是使用新语句分隔符。DELIMITER //

            3 返回合计(带或不带税)

CREATE PROCEDURE productpricing()

        存储过程的完整工作如下:

BEGIN

            -- Name: ordertotal

SELECTAvg(prod_price) AS priceaverage

            -- Parameters: onumber = 订单号

FROMproducts;

            --           taxable = 1为有营业税 0 为没有

END//

            --           ototal = 合计

DELIMITER;

            CREATE  PROCEDURE ordertotal(

其中DELIMITER//告诉命令行实用程序使用//作为新的语句结束符,可以看到表示存储过程结束的END定义END//而不是END;作为语句结束。最后使用DELIMITER ;恢复原来的语句结束符。然后调用结果如下:

            IN onumber INT,

mysql> CALL productpricing();

            IN taxable BOOLEAN,

--------------

            OUT ototal DECIMAL(8,2)

| priceaverage |

            -- COMMENT()中的内容将在SHOW PROCEDURE STATUS ordertotal()中显示,其备注作用

--------------

            ) COMMENT 'Obtain order total , optionally adding tax'

| 16.133571 |

            BEGIN

--------------

            -- 定义total局部变量

1 row in set (0.30 sec)

            DECLARE total DECIMAL(8,2)

Query OK, 0 rows affected (0.30 sec)

            DECLARE taxrate INT DEFAULT 6;

23.2删除存储过程

 

DROP PROCEDURE productpricing;//当不存在时报错

            -- 获得订单的合计,并将结果存储到局部变量total中

DROP PROCEDURE productpricing IF EXISTS;//仅当存在时删除,不存在时不报错

            SELECT Sum(item_price*quantity)

23.3使用参数

            FROM orderitems

一般,存储过程并不显示结果,而是把结果返回给你指定的变量。

            WHERE order_num = onumber

变量:内存中一个特定的位置,用来临时存储数据。所有MySQL变量必须以@开始。

            INTO total;

CREATE PROCEDURE order(IN onumberINT, OUT ototal DECIMAL(8,2))

 

BEGIN

            -- 判断是否需要增加营业税,如为真,这增加6%的营业税

SELECTSum(item_price*quantity)

            IF taxable THEN

FROMorderitems

            SELECT total (total/100*taxrate) INTO total;

WHEREorder_num = onumber

                  END IF;

INTOototal;

            -- 把局部变量total中才合计传给ototal中

END;

            SELECT total INTO ototal;

此存储过程接受两个参数,每个参数必须指定参数类型。关键字IN指出相应参数用来传递给存储过程,OUT(从存储过程传出),INOUT(对存储过程传入和传出)。存储过程的代码位于BEGIN和END语句内。

            END;

为调用这个存储过程,可使用如下语句:

            此存储过程有很大的变动,首先,增加了注释(前面放置--)。在存储过程复杂性增加时,这样很重要。在存储体中,用DECLARE语句定义了两个局部变量。DECLARE要求制定变量名和数据类型,它也支持可选的默认值(这个例子中taxrate的默认设置为6%),SELECT 语句已经改变,因此其结果存储到total局部变量中而不是ototal。IF语句检查taxable是否为真,如果为真,则用另一SELECT语句增加营业税到局部变量total,最后用另一SELECT语句将total(增加了或没有增加的)保存到ototal中。

CALL ordertotal(2005,@total);

    COMMENT关键字  本列中的存储过程在CREATE PROCEDURE 语句中包含了一个COMMENT值,他不是必需的,但如果给出,将在SHOW PROCEDURE STATUS的结果中显示

为显示此合集,如下

    IF语句   这个例子中给出了MySQL的IF语句的基本用法。IF语句还支持ELSEIF和ELSE子句(前者还使用THEN子句,后者不使用)

SELECT @total;

    检查存储过程

为得到另一个订单的合计信息,需要再次调用存储过程

        为显示用来创建一个存储过程的CREATE语句,使用SHOW CREATE PROCEDURE语句

CALL ordertotal(2009,@total);

            SHOW CREATE PROCEDURE ordertotal;

SELECT @total;

        为了获得包括何时、有谁创建等详细信息的存储过程列表。使用SHOW PROCEDURE STATUS.限制过程状态结果,为了限制其输出,可以使用LIKE指定一个过滤模式,例如:SHOW PROCEDURE STATUS LIKE ''ordertotal;

23.4 建立智能存储过程

MySQL5添加了对游标的支持

只有在存储过程内包含业务规则和智能处理时,他们的威力彩真正显现出来。

    只能用于存储过程

CREATE PROCEDURE ordertotal(

    由前几章可知,mysql检索操作返回一组称为结果集的行。都与mysql语句匹配的行(0行或多行),使用简单的SELECT语句,没有办法得到第一行、下一行或前10行,也不存在每次行地处理所有行的简单方法(相对于成批处理他们)

INonumber INT,

    有时,需要在检索出来的行中前进或后退一行或多行。这就是使用游标的原因。游标(cursor)是一个存储在MYSQL服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。

INtaxable BOOLEAN,

    游标主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或做出更改。

OUTototal DECIMAL(8,2)

    使用游标

) COMMENT 'Obtain order total, optionallyadding tax'

        使用游标涉及几个明确的步骤:

BEGIN

            1 在能够使用游标前,必须声明(定义)它,这个过程实际上没有检索数据,它只是定义要使用的SELECT语句

--Declare variable for total

            2 一旦声明后,必须打开游标以供使用。这个过程用钱吗定义的SELECT语句吧数据实际检索出来

DECLARE total DECIMAL(8,2);

            3 对于填有数据的游标,根据需要取出(检索)的各行

--DECLARE tax percentage

            4 在接受游标使用时,必须关闭它 如果不明确关闭游标,MySQL将会在到达END语句时自动关闭它

DECLARE taxrate INT DEFAULT 6;

    创建游标

--Getthe order total

        游标可用DECLARE 语句创建。 DECLARE命名游标,并定义相应的SELECT语句。根据需要选择带有WHERE和其他子句。如:下面第一名为ordernumbers的游标,使用了检索所有订单的SELECT语句

SELECT Sum(item_price*quantity)

            CREATE PROCEDURE processorders()

FROM orderitems

            BEGIN

WHERE order_num = onumber

            DECLARE ordernumbers CURSOR

INTO total;

            FOR

--Is this taxable?

            SELECT order_num FROM orders ;

IFtaxable THEN

            END;

--Yes, so add taxrate to total

            存储过程处理完成后,游标就消失,因为它局限于存储过程

SELECT total (total/100*taxrate) INTO total;

    打开和关闭游标

ENDIF;

            CREATE PROCEDURE processorders()

--And finally,save to out variable

            BEGIN

SELECT total INTO ototal;

            DECLAREordernumbers CURSOR

END;

            FOR

这里COMMERNT关键字不是必须的,但如果给出,将在SHOW PROCEDURE STATU的结果中显示。

            SELECT order_num FROM orders ;

MySQL除了IF语句,还指出ELSEIF和ELSE子句(ELSEIF还须用THEN, ELSE不使用)

            Open ordernumbers ;

调用并显示如下结果1:如下

            Close ordernumbers ;  //CLOSE释放游标使用的所有内部内存和资源,因此,每个游标不需要时都应该关闭

mysql> CALL ordertotal(20005,0,@total);

            END;

Query OK, 0 rows affected (0.05 sec)

    使用游标数据

mysql> SELECT @total;

        在一个游标被打开后,可以使用FETCH语句分别访问它的每一行。FETCH指定检索什么数据(所需的要列),检索出来的数据存储在什么地方。它还向前移动游标中的内部行指针,使下一条FETCH语句检索下一行,相当于PHP中的each()函数

--------

循环检索数据,从第一行到最后一行

| @total |

            CREATE PROCEDURE processorders()

--------

            BEGIN

| 149.87 |

            -- 声明局部变量

--------

            DECLARE done BOOLEAN DEFAULT 0;

1 row in set (0.00 sec)

            DECLARE o INT;

调用并显示如下结果2如下

 

mysql> CALL ordertotal(20005,1,@total);

            DECLAREordernumbers CURSOR

Query OK, 0 rows affected, 1 warning (0.00sec)

            FOR

mysql> SELECT @total;

            SELECT order_num FROM orders ;

--------

            -- 当SQLSTATE为02000时设置done值为1

| @total |

            DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

--------

            --打开游标

| 158.86 |

            Open ordernumbers ;

--------

            -- 开始循环

1 row in set (0.00 sec)

            REPEAT

23.5检查存储过程

            -- 把当前行的值赋给声明的局部变量o中

为了显示用来创建一个存储过程的CREATE语句,使用SHOW CREATE PROCEDURE语句:

            FETCH ordernumbers INTO o;

SHOW CREATE PROCEDURE ordertotal;

            -- 当done为真时停止循环

为了获得包括何时,由谁创建等详细信息的存储过程列表,使用SHOW PROCEDURE STATUS,并且可用LIKE指定一个过滤模式,例如

            UNTIL done END REPEAT;

SHOW PROCEDURE STATUS LIKE ‘ordertotal’;

            --关闭游标

24使用游标

            Close ordernumbers ;  //CLOSE释放游标使用的所有内部内存和资源,因此,每个游标不需要时都应该关闭

有时,需要在检索出来的行中前进或后退一行或多行。这就是使用游标的原因。游标是一个存储在MySQL服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结构集。在存储了游标之后,应用程序可以根据需要滚动或浏览或更改其中的数据。

            END;

24.1使用游标

        语句中定义了CONTINUE HANDLER ,它是在条件出现时被执行的代码。这里,它指出当SQLSTATE '02000'出现时,SET done=1。SQLSTATE '02000'是一个未找到条件,当REPEAT没有更多的行供循环时,出现这个条件。

步骤:

    DECLARE 语句次序  用DECLARE语句定义局部变量必须在定义任意游标或句柄之前定义,而句柄必须在游标之后定义。不遵守此规则就会出错

1) 在使用有游标前,必须声明它。这个过程实际上没有检索数据,它只是ing医药使用的SELECT语句

重复和循环   除这里使用REPEAT语句外,MySQL还支持循环语句,它可用来重复执行代码,直到使用LEAVE语句手动退出为止。通常REPEAT语句的语法使它更适合于对游标进行的循环。

2) 一旦声明后,必须打开游标供使用。这个过程用前面定义的SELECT语句把数据实际检索出来。

为了把这些内容组织起来,这次吧取出的数据进行某种实际的处理

3) 对于填有数据的游标,根据需要取出各行

        CREATE PROCEDURE processorders()

4) 在结束游标使用时,必须关闭游标

        BEGIN

24.2创建游标和使用游标数据

        -- 声明局部变量

在一个游标被打开后,可以使用FETCH语句分别访问它的每一行,FETCH指定检索什么数据,检索出来的数据存储在什么地方。它还向前移动游标中的内部行指针,使下一条FETCH语句检索下一行。

        DECLARE done BOOLEAN DEFAULT 0;

举例如下:

        DECLARE o INT;

CREATE PROCEDURE processorders()

        DECLARE t DECIMAL(8,2)

BEGIN

 

--Declarelocal variables

        DECLAREordernumbers CURSOR

DECLAREdone BOOLEAN DEFAULT 0;

        FOR

DECLAREo INT;

        SELECT order_num FROM orders ;

DECLAREt DECIMAL(8,2);

        -- 当SQLSTATE为02000时设置done值为1

--Declarethe cursor

        DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

DECLAREordernumbers CURSOR

        -- 创建一个ordertotals的表

FOR

        CREATE TABLE IF NOT EXISTS ordertotals( order_num INT , total DECIMAL(8,2))

SELECTorder_num FROM orders;

        --打开游标

--Declarecontinue handler

        Open ordernumbers ;

DECLARECONTINUE HANDLER FOR SQLSTATE ‘02000’ SET done = 1;

        -- 开始循环

--Createa table to store the results

        REPEAT

CREATETABLE IF NOT EXISTS ordertotals

        -- 把当前行的值赋给声明的局部变量o中

(order_numINT, total DECIMAL(8,2));

        FETCH ordernumbers INTO o;

--Openthe cursor

        -- 用上文讲到的ordertotal存储过程并传入参数,返回营业税计算后的合计传给t变量

OPENordernumbers;

        CALL ordertotal(o , 1 ,t)

--Loopthrough all rows

        -- 把订单号和合计插入到新建的ordertotals表中

REPEAT

        INSERT INTO ordertotals(order_num, total) VALUES(o , t);

--Getorder number

        -- 当done为真时停止循环

FETCH ordernumbers INTO o;

        UNTIL done END REPEAT;

--Getthe total for this order

        --关闭游标

CALL ordertotal(o,1,t);

        Close ordernumbers ;  //CLOSE释放游标使用的所有内部内存和资源,因此,每个游标不需要时都应该关闭

--Insertorder and total into ordertotals

        END;

INSERTINTO ordertotals(order_num,total)

        最后SELECT * FROM ordertotals就能查看结果了

VALUES(o,t);

 使用触发器

--ENDOF LOOP

    MySQL5版本后支持触发器

UNITLdone END REPEAT;

    只有表支持触发器,视图不支持触发器

--Closethe cursor;

    MySQL语句在需要的时被执行,存储过程也是如此,但是如果你想要某条语句(或某些语句)在事件发生时自动执行,那该怎么办呢:例如:

CLOSEordernumbers;

        1 每增加一个顾客到某个数据库表时,都检查其电话号码格式是否正确,区的缩写是否为大写

END;

        2 每当订购一个产品时,都从库存数量中减少订购的数量

在这个例子中,FETCH在REPEAT内,因此它反复执行直到done为真(由UNTIL done END REPEAT;规定)。为使它起作用,用一个DEFAULT 0定义变量done。然后用DECLARE CONTINUE HANDLER FOR SQLSTATE ‘02000’ SET done =1;这条语句定义一个CONTINUEHANDLER,它是在条件出现时被执行的代码。这里,它指出当SQLSTATE ‘02000’出现时,SET done=1。SQLSTATE ‘02000’是一个未找到条件,当REPEAT由于没有更多的行工循环而不能继续时,出现这个条件。这里还调用了另外一个存储过程CALL ordertotal(o,1,t);这是在前一章创建的存储过程,实现计算每个订单带税额合计。此存储过程不返回数据,但它能够创建和填充另一个表。

        3 无论何时删除一行,都在某个存档中保留一个副本

可以用以下语句执行存储过程和查看存储结果:

    这写例子的共同之处是他们都需要在某个表发生更改时自动处理。这就是触发器。触发器是MySQL响应一下任意语句而自动执行的一条MySQL语句(或位于BEGIN和END语句之间的一组语句)

mysql> CALL processorders();

    1 DELETE

mysql> SELECT * FROM ordertotals;

    2 INSERT

----------- ---------

    3 UPDATE

| order_num | total |

    其他的MySQL语句不支持触发器

----------- ---------

    创建触发器

| 20005 | 158.86 |

        创建触发器需要给出4条信息

| 20006 | 58.30 |

        1 唯一的触发器名;  //保存每个数据库中的触发器名唯一

| 20007 | 1060.00 |

        2 触发器关联的表;

| 20008 | 132.50 |

        3 触发器应该响应的活动(DELETE、INSERT或UPDATE)

| 20009 | 40.78 |

        4 触发器何时执行(处理前还是后,前是BEFORE 后是AFTER)

----------- ---------

        创建触发器用CREATE TRIGGER

6 rows in set (0.00 sec)

        CREATE TRIGGER newproduct AFTER INSERT ON products

这样我们就得到了存储过程,游标,逐行处理以及存储过程调用其他存储工程的一个完整的工作样例。

        FOR EACH ROW SELECT'Product added'

25.使用触发器

       创建新触发器newproduct ,它将在INSERT语句成功执行后执行。这个触发器还镇定FOR EACH ROW,因此代码对每个插入的行执行。这个例子作用是文本对每个插入的行显示一次product added

25.1触发器

        FOR EACH ROW 针对每个行都有作用,避免了INSERT一次插入多条语句

触发器是MySQL响应一下任意语句而自动执行的一条MySQL语句(或位于BEGIN和END语句之间的一组语句):

    触发器定义规则

DELETE

        触发器按每个表每个事件每次地定义,每个表每个事件每次只允许定义一个触发器,因此,每个表最多定义6个触发器(每条INSERT UPDATE 和DELETE的之前和之后)。单个触发器不能与多个事件或多个表关联,所以,如果你需要一个对INSERT 和UPDATE存储执行的触发器,则应该定义两个触发器

INSERT

    触发器失败  如果BEFORE(之前)触发器失败,则MySQL将不执行SQL语句的请求操作,此外,如果BEFORE触发器或语句本身失败,MySQL将不执行AFTER(之后)触发器

UPDATE

    删除触发器

25.2创建触发器

        DROP TRIGGER newproduct;

创建触发器时,需要给出4条信息:

        触发器不能更新或覆盖,所以修改触发器只能先删除再创建

1) 唯一的触发器名;

    使用触发器

2) 触发器关联的表

        我们来看看每种触发器以及它们的差别

3) 触发器应该响应的活动(DELETE、INSERT或UPDATE)

    INSERT 触发器

4) 触发器何时执行(处理之前或之后)

        INSERT触发器在INSERT语句执行之前或之后执行。需要知道以下几点:

只有表可以支持触发器,视图不支持(临时表也不支持)。

    1 在INSERT触发器代码内,可引用一个名为NEW的虚拟表,访问被插入的行

CREATE TRIGGER newproduct AFTER INSERT ONproducts FOR EACH ROW SELECT 'd';

    2 在BEFORE INSERT触发器中,NEW中的值也可以被更新(允许更改插入的值)

这里用CREATE TRIGGER创建一个名为newproduct的新触发器。触发器可在一个操作发生之前或之后执行,这里给出了AFTER INSERT,所以触发器将在INSERT语句成功后执行。这个触发器还制定了FOR EACH ROW,因此代码对每个插入行执行。在这个例子中,文本Product added将对每个插入的行显示一次。PS.在我的MySQL版本中,不能成功实现,会提示不能返回结果集Not allowed to return a result set from a trigger错误。不知道是MySQL版本问题还是MySQL必知必会中的错误。

    3 对于AUTO_INCREMENT列,NEW在INSERT执行之前包含0,在INSERT执行之后包含新的自动生成值

触发器按每个表每个时间每次的定义,每个表每个时间每次只能定义一个触发器,因此一个表最多支持6个触发器(INSERT,UPDATE和DELETE之前或之后)。

        提示:通常BEFORE用于数据验证和净化(目的是保证插入表中的数据确实是需要的数据)。本提示也适用于UPDATE触发器

25.3删除触发器:

    DELETE 触发器

DROP TRIGGER newproduct;

        DELETE触发器在语句执行之前还是之后执行,需要知道以下几点:

25.4使用触发器

    1 在DELETE触发器代码内,你可以引用一个名为OLD的虚拟表,访问被删除的行;

25.4.1 INSERT触发器

    2 OLD中的值全部是只读的,不能更新

1)在INSERT触发器代码内,可引用一个名为NEW的虚拟表,访问被插入的行;

        例子演示适用OLD保存将要除的行到一个存档表中

2)在BEFORE INSERT触发器中,NEW中的值可以被更新(允许更改被插入的值)

        CREATE TRIGGERdeleteorder BEFORE DELETE ON orders

3)对于AUTO_INCREMENT列,NEW在INSERRT执行之前包含0,在执行之后包含新的自动生成的值。

        FOR EACH ROW

CREATE TRIGGER neworder AFTER INSERT ONorders FOR EACH ROW SELECT NEW.ORDER_num;

        BEGIN  

25.4.2DELETE触发器

        INSERT INTO archive_orders(order_num , order_date , cust_id)

1)在DELEYE触发器代码内,你可以引用一个名为OLD的虚拟表,访问被删除的行

        VALUES(OLD.order_num , OLD.order_date , OLD.cust_id);

2)OLD中的值全部都是只读的,不能更新。

        END;

CREATE TRIGGER deleteorder BEFORE DELETE ONorders

        //此处的BEGIN  END块是非必需的,可以没有

FOR EACH ROW

    在任何订单删除之前执行这个触发器,它适用一条INSERT语句将OLD中的值(将要删除的值)保存到一个名为archive_orders的存档表中

BEGIN

    BEFORE DELETE触发器的优点是(相对于AFTER DELETE触发器),如果由于某种原因,订单不能被存档,DELETE本身将被放弃执行。

INSERT INTO

    多语言触发器  正如上面所见,触发器deleteorder 使用了BEGIN和END语句标记触发器体。这在此例中并不是必需的,不过也没有害处。使用BEGIN  END块的好处是触发器能容纳多条SQL语句。

archive_orderss(order_num,order_date,cust_id)

    UPDATE触发器

VALUES(OLD.order_num,OLD.order_date,OLD.cust_id);

        UPDATE触发器在语句执行之前还是之后执行,需要知道以下几点:

END;

        1 在UPDATE触发器代码中,你可以引用一个名为OLD的虚拟表访问(UPDATE语句前)的值,引用一名为NEW的虚拟表访问新更新的值

25.5 UPDATE触发器

        2 在BEFORE UPDATE触发器中,NEW中的值可能被更新,(允许更改将要用于UPDATE语句中的值)

1)可以用OLD的虚拟表访问以前的值,也可以用名为NEW的虚拟表访问新更新的值

        3 OLD中的值全都是只读的,不能更新

2)在BEFFORE UPDATE触发器中,NEW中的值可能也被更新

            例子:保证州名的缩写总是大写(不管UPDATE语句给出的是大写还是小写)

3)OLD中的值全部都是只读的,不能更新

            CREATE TRIGGER updatevendor BEFORE UPDATE ON vendores FOR EACH ROW SETNEW.vend_state = Upper(NEW.vend_state)

26.管理事务处理

    触发器的进一步介绍

事务处理可以用来维护数据库的完整性,它保证成批的MySQL操作要么完全执行,要么完全不执行。

    1 与其他DBMS相比,MySQL5中支持的触发器相当初级。以后可能会增强

术语:

    2 创建触发器可能需要特殊的安全访问权限,但是触发器的执行时自动的.如果INSERT UPDATE DELETE能执行,触发器就能执行

事务:指一组SQL语句

    3 应该用触发器来保证数据的一致性(大小写、格式等)。在触发器中执行这种类型的处理的优点是它总是进行这个处理,而且是透明地进行,与客户机应用无关

回退:指撤销指定SQL语句的过程

    4 触发器的一种非常有意义的使用创建审计跟踪。使用触发器把更改(如果需要,甚至还有之前和之后的状态)记录到另一表非常容易

提交:指将未存储的SQL语句结果写入数据库表

    5 遗憾的是,MySQL触发器中不支持CALL语句,这表示不能从触发器中调用存储过程。所需要的存储过程代码需要复制到触发器内

保留点:值事务处理中设置的临时占位符,你可以对它发布回退。

 转载请注明出处,谢谢合作!

26.1控制事务处理

 

管理事务处理的关键在于将SQL语句组分解为逻辑块,并明确规定数据何时应该回退,何时不应该回退。

 

START TRANSACTION//标记是事务开始

 

26.2使用ROLLBACK

ROLLBACK用来回退MySQL语句

SELECT * FROM ordertotals;

START TRANSACTION;

DELETE FROM ordertotals;

SELECT * FROM ordertotals;

ROLLBACK;

SELECT * FROM ordertotals;

依次执行上面语句,可以看到删除的表格内容又被回退了。

ROLLBACK只能在一个事务处理内使用(在执行一条STARTTRANSACTION命令之后)。

26.3使用COMMIT

一般的MySQL都是直接对数据库表执行和编写的,这是隐含提交。但在事务处理块中,提交不会隐含地进行。为进行明确的提交,使用COMMIT语句,如下所示:

START TRANACTION;

DELETE FROM orderitems WHERE order_num =20010;

DELETE FROM orders WHERE order_num = 20010;

COMMIT;

如果第一条起作用,第二条失败,则事务不处理,也就是两条DELETE不会被提交。

26.4使用保留点

简单的ROLLBACK和COMMIT语句就可以写入或撤销整个事务处理。但是,只是对简单的事务处理才嫩这样做,更复杂的事务处理可能需要部分提交或回退。

为了支持回退部分事务处理,必须使用保留点,可如下使用SAVEPOINR语句:

SAVEPOINT delete1;

每个保留点都表示它的唯一名字,以便回退时,MySQL知道要回退到何处。

ROLLBACK TO delete1;

26.5 更改默认的提交行为

为指示MySQL不自动提交更改,需要使用以下语句:

SET autocommit = 0;

27.全球化和本地化

CREATETABLE mytable

(

Column1 INT,

Column2 VARCHAR(0)

)DEAULT CHARACTER SET hebrew CLLATEhebrew_general_ci;

这条语句创建一个表,并且制定一个字符集和一个校对顺序

SHOW CHARACTER SET;//可以查看所支持的字符集完整列表

SHOW COLLATION; //查看所支持的校对完整列表

28.安全管理

管理用户

USE mysql;

SELECT user FROM user;

Mysql数据库有一个名为user的表,它包含所有用户账号。User表有一个user列。

28.1创建用户账户

为创建新用户账户,使用CREATE USER语句

CREATE USER ben IDENTIFIED BY ‘[email protected]$$w0rd’;

创建一个用户名为ben的用户,口令为[email protected]$$w0rd。

RENAME USER ben TO bforta;

28.2删除用户账号

DROP USER bforta;

28.3设置访问权限

mysql> SHOW GRANTS FOR bforta;

-------------------------------------------------------------------------------

------------------------

| Grants for [email protected]%

|

-------------------------------------------------------------------------------

------------------------

| GRANT USAGE ON *.* TO 'bforta'@'%'IDENTIFIED BY PASSWORD '*A6210E6C376AADB5A6

9274F8C3D15B788433A9EB' |

-------------------------------------------------------------------------------

------------------------

1 row in set (0.00 sec)

输出结果显示用户bforta有一个权限USAGE ON *.*。USAGE表示没有权限,所以USAGE ON *.*表示在任意数据库和人意表上对任何东西都没有权限。

使用GRANT设置权限,需要给出以下信息:
1)要授予的权限

2)被授予访问权限的数据库或表

3) 用户名

GRANT SELECT ON crashcourse.* TO bforta;

赋予bforta在crashcourse.*拥有SELECT权限。

在此显示权限如下:

SHOW GRANTS FOR bforta;

-------------------------------------------------------------------------------

------------------------

| Grants for [email protected]%

|

-------------------------------------------------------------------------------

------------------------

| GRANT USAGE ON *.* TO 'bforta'@'%'IDENTIFIED BY PASSWORD '*A6210E6C376AADB5A6

9274F8C3D15B788433A9EB' |

| GRANT SELECT ON `crashcourse`.* TO'bforta'@'%'

|

-------------------------------------------------------------------------------

------------------------

2 rows in set (0.00 sec)

可以用REVOKE取消权限。

REVOKE SELECT ON crashcourse.* FROM bforta;

28.4更改口令

更新用户口令

SET PASSWORD FOR bforta = Password(‘[email protected]$$w0rd’);

设置自己的口令

SET PASSWOR = Password(‘n3w [email protected]$$w0rd’);

第29章数据库维护

ANALYZE TABLE:用来检查表键是否正确

CHECK TABLE:用来针对许多问题对表进行检查

21.1.创建表 CREATE TABLE创建表,必须给出下列信息: 1) 新表的名字,在关键字CREATETABLE之后 2) 表列的名字和定义,用逗...

本文由澳门新萄京官方网站发布于数据库网络,转载请注明出处:澳门新萄京官方网站:至于Mysql存款和储蓄进程及

关键词: