当前位置:七道奇文章资讯数据防范MySQL防范
日期:2012-03-15 15:29:00  来源:本站整理

怎样编写可重用的MySQL查询?[MySQL防范]

赞助商链接



  本文“怎样编写可重用的MySQL查询?[MySQL防范]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

  当人们说起可重用的查询的时刻,当即映入脑海的常常就是存储历程了.固然这些存储历程是编写可重用代码不可分割的一部份,但要记着的是,它们只是很少的一部份罢了,而非全部.此外,别的可重用代码包含视图、内置函数以及用户定义的函数.在本文中,我们将向读者具体介绍若何组合这些元素,以令我们的挑选语句可以更好的实用于各种查询.

  步骤/办法

  关于视图

  视图的用处很多,比方简化复杂的情势及查询,大概供应安全性等等.视图供应安全性的一种途径是对开辟者躲藏审计字段.视图还可通过削减列的数目来提高性能.这个设法是只引用索引字段,而索引字段的搜索速度是非常之快的.实际上,这种设法实现起来很吃力,因为你必须确保不会拜候躲藏列.但是,我们这里主如果操纵视图模拟两个或更多个表之间的衔接,以降低查询的复杂性.很多时刻,要想将数据库顶用户的概要信息整理成符合第三范式的情势,大概需求多达六次衔接操作,比方:

  select * from Users u

  inner join UserPhoneNumbers upnon u.user_id = upn.user_id inner join

  UserScreenNames usnon u.user_id = usn.user_id inner join

  UserAffiliations ua on u.user_id = ua.user_id inner join

  Affiliations a on a.affiliation_id = ua.affiliation_id inner join

  UserWorkHistory uwhon u.user_id = uwh.user_id inner join Affiliations wa

  on uwh.affiliation_id= wa.affiliation_id

  下面,我们用一个视图来替换上面的查找历程:

  CREATE VIEW `vusers`AS select * from Users u inner join

  UserPhoneNumbers upnon

  u.user_id = upn.user_id inner join UserScreenNames

  usnon u.user_id = usn.user_id inner join

  UserAffiliations ua on u.user_id = ua.user_id inner join Affiliations a

  on a.affiliation_id = ua.affiliation_id

  inner join UserWorkHistory uwhon u.user_id = uwh.user_id

  inner join Affiliations wa on uwh.affiliation_id= wa.affiliation_id;

  目前,我们可以通过以下简单的挑选语句来检索用户概要信息了:

  select * from vusers uwhere u.user_id = 100

  关于MySQL内置函数

  GROUP_CONCAT()函数可以用来堆积表中的全部行,并返回构成穿插表水平轴的SELECT列表.实际上,这使得将穿插表的挑选语句移植到存储历程中成为大概.其他的函数,如Count()、Month()和MonthName(),以及过滤语句,如CASE WHEN ELSE,都可以让我们的代码更具通用性.

  成立自己的函数

  假如在MySQL内建的函数中没有我们所想要的,那么我们无妨自己着手,丰衣足食. 在编写自己的函数的时刻,一定要考虑到该函数的通用性.

  下面是一个示例函数,用来查抄能否指定了强迫性的存储历程参数.这里不答应利用空行大概空白符,所以该函数将举行呼应的查抄:

  BEGIN DECLARE isEmptyTINYINT;

  SET isEmpty= (param_nameIS NULL or char_length(trim(param_name))= 0);

  RETURN isEmpty;

  END

  注意,在我们的函数中调用了内建的两个函数,即char_length()和trim().目前,我们总可以将其作为一个通用函数利用了.

  需求提醒的是,在我们编写自己的函数之前,最好先在网上搜索一下,看看别人能否已经做过这项工作了,免得反复相同的工作.这时,我们要分外留神那些MySQL函数仓库站点,我们极大概在这里找到所需的函数.

  存储历程

  我们知道,存储历程可以起到代码模块化和集合化的作用.但是,将SQL代码放入存储历程本身并不意味着就可以提高通用性大概可重用性.举例来说,下面的语句将生成一份反映各员工去年奖金总数的报告:

  SELECT e.name, e.salary,

  COUNT(b.bonus_id)AS 'Total Bonuses'FROM employees e

  LEFT OUTER JOIN

  (SELECT emp_id, bonus_id FROM bonusesWHERE YEAR(award_date)= 2010)AS b

  ON e.id= b.emp_idGROUP BY e.id;

  下面我们将其改变成一个存储历程:

  CREATE PROCEDURE `p_2010_bonuses_lst`()

  LANGUAGE SQL

  NOT DETERMINISTIC CONTAINS SQL

  SQL SECURITY DEFINER BEGIN SELECT e.name, e.salary,

  COUNT(b.bonus_id)AS 'Total Bonuses'FROM employees e

  LEFT OUTER JOIN

  (SELECT emp_id, bonus_idFROM bonusesWHERE YEAR(award_date)= 2010)AS b

  ON e.id= b.emp_idGROUP BY e.id;

  END;

  目前,其他人或程序便可以便利的利用这个历程了,不过这里有个时间限制,就是只能在明年之前利用.但是,我们为什么要成立这种有限制的东西呢?因为,我们每年都大概需求生成类似的报告,所以下面我们要去掉这个时间限制.

  为此,我们将该历程中的硬编码的日期删撤除,以下所示:

  CREATE PROCEDURE `p_yearly_bonuses_lst`(IN `@year`INT)

  LANGUAGE SQL

  NOT DETERMINISTIC CONTAINS SQL

  SQL SECURITY DEFINER BEGIN SELECT e.name, e.salary,

  COUNT(b.bonus_id)AS 'Total Bonuses'FROM employees e

  LEFT OUTER JOIN

  (SELECT emp_id, bonus_idFROM bonusesWHERE YEAR(award_date)= @year)AS b ON e.id= b.emp_idGROUP BY e.id;

  END;

  作为一名有长进心的开辟人员,我们会自问能否可以做得更好呢?客户程序大概对起始日期和完毕日期方面有更高的机动性要求,比方他们大概要求日期范围与财政年度一致.从这方面考虑,不管客户程序能否要求,我们的都必须供应一个起始日期和终止日期参数. MySQL有一个非常不错的BETWEEN运算符,可以用来处理某个范围内的值.

  下面我们就将其用于起始日期和终止日期:

  CREATE PROCEDURE `p_bonuses_lst`(IN `@StartDate`DATETIME, IN `@EndDate` DATETIME )

  LANGUAGE SQL

  NOT DETERMINISTIC CONTAINS SQL

  SQL SECURITY DEFINER

  BEGIN

  SELECT e.name, e.salary,

  COUNT(b.bonus_id)AS 'Total Bonuses'FROM employees e

  LEFT OUTER JOIN

  (SELECT emp_id, bonus_id FROM bonuses WHERE award_dateBetween @StartDate AND @EndDate)AS b

  ON e.id= b.emp_idGROUP BY e.id;

  END;

  注意事项

  按照部分性原理,目前履行的操作,近期内极大概会再次履行该操作,所以提高可重用性是非常有帮忙的.


  以上是“怎样编写可重用的MySQL查询?[MySQL防范]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • 怎样编写可重用的MySQL查询?
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .