• 第九部分 视图和存储过程


    视图

    视图是虚拟的表。与包含数据的表不一样,视图只包含使用动态检索数据的查询,并不包含表中应该有的任何列或数据,即包含的不是数据。视图提供了一种MySQL的SELECT语句层次的封装,可用来简化数据处理以及重新格式化基础数据或保护基础数据。

    为什么使用视图?使用视图的作用主要有以下几个理由

    • 重用SQL语句;
    • 简化复杂的SQL操作。在编写查询后,可以方便地重用它而不必知道它的基本查询细节;
    • 使用表的组成部分而不是整个表;
    • 保护数据,可以给用户授予表的特定部分的访问权限而不是整个表的访问权限;
    • 更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。
    • 视图的规则和限制
    • 视图必须唯一命名,即不能给视图取与别的视图或表相同的名字;
    • 对于可以创建的视图数目没有限制;
    • 为了创建视图,必须具有足够的访问权限。这些权限通常由数据库管理人员授予;
    • 视图可以嵌套,即可以利用其他视图中检索数据的查询来构造一个视图;
    • ORDER BY可以用在视图中,但如果从该视图检索数据的SELECT中也含有ORDER BY,那么该视图中的ORDER BY将被覆盖;
    • 视图不能索引,也不能有关联的触发器或默认值;
    • 视图可以和表一起使用。

    1.使用视图

    • 视图用CREATE VIEW语句来创建;
    • 使用SHOW CREATE VIEW viewname;来查看创建视图的语句;
    • 用DROP删除视图,即DROP VIEW viewname;

    更新视图时,可以先用DROP再用CREATE,也可以直接用CREATE OR REPLACE VIEW。如果要更新的视图不存在,则第2条更新语句会创建一个视图;如果要更新的视图存在,则第2条更新语句会替换原有视图。

    示例1:创建一个名为productcustomers的视图,返回已订购了任意产品的所有客户的列表

    SQL语句:CREATE VIEW productcustomers AS SELECT cust_name, cust_contact FROM customers, orders, orderitems WHERE customers.cust_id = orders.cust_id AND orderitems.order_num=orders.order_num;

    示例2:检索订购某个特定产品的客户

    SQL语句:SELECT cust_name, cust_contact FROM productcustomers WHERE prod_id = 'TNT2';

    示例3:检索某个特定订单中的物品,计算每种物品的总价格

    SQL语句:CREATE VIEW expandprice AS SELECT prod_id, quantity, item_price, quantity*item_price AS expand_price FROM orderitems;

    SQL语句:SELECT * FROM expandprice WHERE order_num = 2005;

    (1) 用视图重新格式化检索出的数据

    示例:单个组合计算列中返回供应商名和位置

    SQL语句:CREATE VIEW vendorlocations AS SELECT Contac(RTrim(vend_name)), '(', RTrim(vend_country), ')') AS vend_title FROM vendor ORDER BY vend_name;

    SQL语句:SELECT * FROM vendorlocations;

    (2) 用视图过滤数据

    示例:过滤没有电子邮件地址的客户

    SQL语句:CREATE VIEW customeremaillist AS SELECT cust_id, cust_name, cust_email FROM customers WHERE cust_email IS NOT NULL;

    SQL语句:SELECT * FROM customeremaillist;

    2.更新视图

    通常,视图是可更新的,即可以对其使用INSERT、UPDATE、DELETE操作。更新一个视图将更新其基表,因为视图本身没有数据。若对视图增加或删除行,实际上是对其基表增加或删除行。但是,并非所有视图均可以更新。基本上说,如果MySQL不能正确地确定被更新的基数据,则不允许更新。更具体地说,以下几种操作,均不能进行视图的更新

    • 分组(使用GROUP BY和HAVING);
    • 联结;
    • 子查询;
    • 并;
    • 聚集函数(Min()、Count()、Sum()等);
    • DISTINCE;
    • 导出(计算)列。

    存储过程

    简言之,存储过程是为以后的使用而保存的一条或多条MySQL语句的集合。可以将其视为批文件。那么,为什么要使用它们呢?理由主要有以下几点

    • 通过把处理封装在容易使用的单元中,简化复杂的操作。
    • 简化对变动的管理。如果表名、列名或业务逻辑有变化,只需要更改存储过程的代码,使用人员不需要知道这些变化。
    • 提高性能。因为使用存储过程比使用单独的SQL语句要快。

    换句话说,使用存储过程有3个主要的好处,即简单、安全、高性能

    (1) 创建存储过程

    示例1:返回产品平均价格的存储过程(无参数)

    SQL语句:CREATE PROCEDURE productpricing()

    BEGIN

    SELECT Avg(prod_price) AS priceaverage

    FROM products;

    END;

    示例2:返回产品价格的存储过程(有参数)

    SQL语句:CREATE PROCEDURE productpricing(

    OUT pl 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个参数:pl存储产品最低价格,ph存储产品最高价格,pa存储产品平均价格。每个参数必须具有指定的类型,这里使用十进制。关键字OUT指出相应的参数用来从存储过程传出一个值,即返回给调用者。MySQL支持IN(传递给存储过程)、OUT(从存储过程传出)和INOUT(对存储过程传入和传出)类型的参数。

    示例3:使用IN和OUT参数,ordertotal接受订单号并返回该订单的合计

    SQL语句: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,因为要从存储过程中返回合计。

    示例4:考虑这样的场景。你需要获得与以前一样的订单合计,但需要对合计增加营业税,不过只针对某些顾客。那么,需要做下面几件事情:获得合计、把营业税有条件地添加到合并、返回合计。

    SQL语句:CREATE PROCEDURE ordertotal(

    IN onumber INT,

    IN taxable BOOLEAN,

    OUT ototal DECIMAL(8,2)

    )COMMENT 'Obtain order total, optionally adding tax'

    BEGIN

    DECLARE tax DECIMAL(8,2);

    DECLARE taxrate INT DEFAULT 6;

    SELECT Sum(item_price*quantity) FROM orderitems WHERE order_num=onumber INTO total;

    IF taxable THEN

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

    END IF;

    SELECT total INTO ototal;

    END;

    (2) 执行(调用)存储过程

    示例:计算并返回产品的最低、最高和平均价格

    SQL语句:CALL productpricing(@pricelow,@pricehigh,@priceaverage)

    SQL语句:CALL productpriceing();

    SQL语句:SELECT @pricelow,@pricehigh,@priceaverage;

    SQL语句:CALL ordertotal(2005,@total);

    必须给ordertotal传递两个参数,第一个参数为订单号,第二个参数为包含计算出来的合计的变量名。

    SQL语句:CALL ordertotal(2005,0,@total);SELECT @total;

    示例:显示订单2005和@total包含的值合计

    SQL语句:SELECT @total;

    (3) 删除存储过程

    示例:删除存储过程productpricing,注意没有存储过程名后面的()

    SQL语句:DROP PROCEDURE productpricing IF EXISTS;

    (4) 检查存储过程

    示例1:显示用来创建一个存储过程的CREATE语句

    SQL语句:SHOW CREATE PROCEDURE ordertotal;

    示例2:获得包括何时、由谁创建等详细信息的存储过程列表

    SQL语句:SHOW PROCEDURE STATUS LIKE 'ordertotal';

    ----------------------------------- 心之所向,素履所往;生如逆旅,一苇以航。 ------------------------------------------
  • 相关阅读:
    Oracle删除用户和表空间
    PLSQL配置教程
    Oracle 11g client 安装
    oracle 11g 安装
    oracle创建用户空间、导出、导入dmp备份文件方法
    c#关键字
    c#运算符重载
    每天一个Linux命令之date
    linux之2>&1
    每天一个Linux命令之crontab
  • 原文地址:https://www.cnblogs.com/wzw0625/p/12733462.html
Copyright © 2020-2023  润新知