MySQL数据库技术(10)[MySQL防范]
本文“MySQL数据库技术(10)[MySQL防范]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
? 2.4 表达式求值和范例转换
? ? MySQL 答应编写包含常量、函数调用和表列引用的表达式.这些值可操纵差别范例的运算符举行组合,诸如算术运算符或对比运算符.表达式的项可用圆括号来分组.表达式在SELECT 语句的列挑选列表和WHERE 子句中呈现得最为频繁,以下所示:
? ? 所挑选的每列给出了一个表达式,如WHERE 子句中所示的那样.表达式也呈目前DELETE 和U P D ATE 语句的WHERE 子句中,以及呈目前I N S E RT 语句的VALUES( ) 子句中.
? ? 在MySQL 碰到一个表达式时,它对其求值得出后果.比方, (4 * 3)/(4 - 2) 求值得6.表达式求值大概触及范例转换.比方, MySQL 在数960821 用于需求日期值的环境时,将其转换为日期" 1 9 9 6 - 0 8 - 2 1".本节谈论怎样编写MySQL 的表达式,以及在表达式求值中MySQL 所利用的范例转换法则.每个MySQL 的运算符都介绍过了,但MySQL 有那么多的函数,我们只接触过几个.每个运算符和函数的进一步介绍可参阅附录C.
? ? 2.4.1 撰写表达式
? ? 表达式可以只是一个简单的常量,如:
? ? 0 数值常量
? ? "a b c" 串常量
? ? 表达式可以举行函数调用.有的函数需求参数(圆括号中有值),而有的不需求.多个参数应当用逗号脱离.在调用一个函数时,参数旁边可以有空格,但在函数名与圆括号间不能有空格.下面是一些函数例子:
??NOW( ) 无参数函数
? ? STRCMP ("a b c", "d e f") 有两个参数的函数
? ? STRCMP( "a b c", "d e f") 参数旁边有空格是合理的
? ? STRCMP ("a b c", "d e f") 函数名后跟空格是不合理的
? ? 假如函数名后有一个空格, MySQL 的解析程序大概会将函数名注释为一个列名(函数名不是保存字,假如需求的话,可将它们用作列名).后来果是呈现一个语法错误.表达式中可以利用表列.最简单的情形是,当某个列所属的表在上下文中是明确的,则可简单地给出列名对该摆列行引用.下面的每个SELECT 语句中惟一地出了一个表名,因此,列的引用无歧义:
? ? 假如利用哪个表的列不明确,可在列名前加上表名.假如利用哪个数据库中的表也不明确的话,可在表名前加上数据库名.假如只是但乐意思更明显,也可以在无歧义的上下文中操纵这种更为具体的表示情势,如:
? ? 总之,可以组合全部这些值以得到更为复杂的表达式.
? ? 1. 运算符的范例
? ? MySQL 有几种范例的运算符,可用来衔接表达式的项.算术运算符,如表2-15 所示,普通包含加、减、乘、除以及模运算符.在两个操作数都是整数时,"+"、"-"和" *"算术运算用BIGINT(64 位)整数值来完成.而在后果预期为一个整数时,"/"和"%"也是用BIGINT(64 位)整数值来完成的.应当熟习到,假如某个运算触及更大的值,如后果超越64 位,后来果不可意料.
? ? 逻辑运算符如表2 - 1 6所示,对表达式举行预计以肯定其为真(非零)或假(零).M y S Q L包含有C 气势的"& &"、"| |"和"!"运算符,可替换A N D、OR 和N O T.要分外注意"| |"运算符,ANSI SQL 指定"| |"作为串通接符,但在MySQL 中,它表示一个逻辑或运算.假如履行下面的查询,则返回数0:
? ? MySQL 为举行运算,将" a b c"和"d e f"转换为整数,且二者都转换为0, 0与0举行或运算,后果为0.在MySQL 中,必须用CONCAT ("a b c", "d e f") 来完成串的衔接.
? ? 位运算符如表2-17 所示,完成按位"与"和"或",此中后果的每一位按两个操作数的对应位的逻辑AND 或OR 求值.还可以举行位的左移或右移.位运算用BIGINT(64 位)整数值举行.
? ? 对比运算符如表2-18 所示,此中包含测试相对大小或数和串的次序的运算符,以及完成情势匹配和测试NULL 值的运算符."< = >"运算符是MySQL 特有的,在MySQL 3.23版本中引入.
?? 自MySQL 3.23版本起,可以利用B I N A RY 运行符,此运算符可用来将一个串转换为一个二进制串,这个串在对比中是辨别大小写的.下列的第一个对比是不辨别大小写的,但第二个和第三个对比是辨别大小写的:
? ? 没有呼应的NOT BINARY 计算.假如但愿使一个列既能在辨别大小写又能在不辨别大小写的环境中利用,则应当操纵不辨别大小写的列并对但愿辨别大小写的对比利用BINARY.关于操纵二进制串范例(CHAR BINARY、VARCHAR BINARY 和BLOB 范例)定义的列,其对比老是辨别大小写的.为了对这样的列范例实现不辨别大小写的对比,可操纵UPPER( ) 或LOWER( ) 来转换成相同的大小写:
? ? 关于不辨别大小写的串对比,有大概把多个字符认为是相等的,这取决于所用的字符集.比方"e"和"é"关于对比和排序操作大概是相同的.二进制(辨别大小写)对比操纵字符的ASCII 值来完成.
? ? 情势匹配答应查找值而没必要给出切确的直接值.MySQL 操纵LIKE 运算符和通配符"%"(匹配肆意的字符序列)和" _"(匹配肆意单个字符),供应SQL 的情势匹配.MySQL 还基于近似于诸如g r e p、sed 和vi 等Unix 程序中所用的REGEXP 运算符和扩大正规表达式,供应情势匹配.为了完成情势匹配,必须利用这些情势匹配运算符中的某一个;不能利用" =".为了举行相反的情势匹配,可以利用NOT LIKE 或NOT REGEXP.
? ? 除了利用的情势运算符和情势字符差别外,这两种情势匹配还在以下重要的方面存在差别:
? ? ■ 除非至少有一个操作数为二进制串,不然LIKE 是不辨别大小写的.REGEXP 是辨别大小写的.(在MySQL 3.23.4 今后的版本中,除非至少有一个操作数是二进制串,不然REGEXP 是不辨别大小写的.)
? ? ■ 仅当整个串匹配,SQL 才是情势匹配的.仅当呼应的情势在串中某一处呈现,正规表达式才匹配.用于LIKE 运算符的情势可以包含"%"和"_"通配符.比方,情势" F r a n k %"与任何故"F r a n k"起头的串匹配:
? ? 通配符"%"与任何串匹配,此中包含与空字符序列匹配,因此" Frank %"与" Frank"匹配:
? ? 这也表示情势"%"与任何串匹配,此中包含与空串匹配.但是,"%"不与NULL 匹配.事实上,具有NULL 操作数的任何情势匹配都将失利:
? ? MySQL 的LIKE 运算符是不辨别大小写的,除非它至少有一个操作数是二进制串.因此,缺省时" Frank %"与串" Frankly"和"frankly"匹配,但在二进制对比中,它只与此中之一匹配:
? ? 这差别于ANSI SQL 的LIKE 运算符,它是辨别大小写的.通配符可在情势中任何地方给出."% bert"与" Englebert"、"Bert"和"Albert"匹配."% bert %"也与全部这些串匹配,并且还与如像" Berthold"、"Bertram"、和"Alberta"这样
的串匹配.LIKE 所答应的另一个通配符是" _",它与单个字符匹配."_ _"与三个字符的串匹配."c _ t"与"c a t"、"c u t"乃至"c _ t"匹配(因为"_"与自身匹配).为了关掉"%"或" _"的特别含义,与这些字符的直接实例相匹配,需求在它们前面安排一个斜杠("\ %"或"\ _"),如:
? ? MySQL 的另一种情势的情势匹配利用了正规表达式.运算符为REGEXP 而不是L I K E(RLIKE 为REGEXP 的同义词).最常用的正规表达式情势字符以下:‘.’与肆意单个字符匹配:
? ? ‘[ . . . ]’与方括号中肆意字符匹配.可列出由短划线‘ -’脱离的范围端点指定一个字符范围.为了否定这种区间的意义(即与未列出的任何字符匹配),指定‘ ^’作为该区间的第一个字符便可:
? ? ‘*’表示"与其前面字符的肆意数目的字符匹配",因此,如‘ x *’与肆意数目的‘ x’字符匹配,比方:
? ? "肆意数目"包含0个实例,这也就是为什么第二个表达式匹配成功的缘由.‘^pat’和‘pat$’固定了一种情势匹配,从而情势pat 只在它呈目前串的前头时匹配,而‘ ^pat$’只在pat 匹配整个串时匹配,比方:
? ? REGEXP 情势可从某个表列中取出,固然假如该列包含几个差别的值时,这样做比常量情势慢.每当列值更改时,必须对情势举行查抄并转换成内部情势.MySQL 的正规表达式匹配还有一些特别的情势字符.要理解更具体信息请参阅附录C.
? ? 2. 运算符的优先级
? ? 当求一个表达式的值时,首先查看运算符以决意运算的先后次序.有的运算符具有较高的优先级;比方,乘和除比加和减的优先级更高.下面的两个表达式是等价的,因为" *"和"/"先于"+"和"-"计算:
? ? 下面列出了运算符的优先级,从高到低.列在同一行中的运算符具有相同的优先级.优先级较高的运算符在优先级较低的运算符之前求值.
? ? 可用圆括号来忽视运算符的优先级并改变表达式的求值次序,如:
? ? 3. 表达式中的NULL 值
? ? 请注意,在表达式中利用NULL 值时,后来果有大概呈现不测.下列原则将有助于避免出问题.假如将NULL 作为算术运算或位运算符的一个操作数,后来果为N U L L:
? ? 假如将NULL 用于逻辑运算符,NULL 被认为是假:
? ? NULL 作为肆意对比运算符的操作数,除< = >、IS NULL 和IS NOT NULL 运算符(它们是专门扩大来处理NULL 值的)外,将产生一个NULL 后果.如:
? ? 假如给函数一个NULL 参数,除了那些处理NULL 参数的函数外,普通返回一个N U L L后果.比方,IFNULL( ) 可以处理NULL 参数并适本地返回真或假.STRCMP( ) 盼望一个非NULL 的参数;假如它发现传给它的是一个NULL 参数,则返回NULL 而不是真或假.在排序操作中,NULL 值被归到一同.在升序排序中, NULL 将排在全部非NULL 值之前(包含空串),而在降序排序中,NULL 将排在全部非NULL 值之后.
? ? 2.4.2 范例转换
? ? MySQL 按照所履行的操作范例,自动地举行大量的范例转换,任什么时刻候,只要将一个范例的值用于需求另一范例值的场所,就会举行这种转换.下面是需求举行范例转换的缘由:
? ? ■ 操作数转换为合适于某种运算符求值的范例.
? ? ■ 函数参数转换为函数所需的范例.
? ? ■ 转换某个值以便赋给一个具有差别范例的表列.下列表达式触及范例转换.它由加运算符" +"和两个操作数1 和"2" 构成:
? ? 1+"2"
? ? 此中操作数的范例差别,一个是数,另一个是串,因此, MySQL 对此中之一举行转换以便使它们两个具有相同的范例.但是应当转换哪一个呢?因为,"+"是一个数值运算符,所以MySQL 但愿操作数为数,因此,将串" 2"转换为数2.然后求此表达式的值得出3.再举一例.C O N C AT( ) 函数衔接串产生一个更长的串作为后果.为了完成此工作,它将参数注释为串,而不管参数实际是何范例.假如传送给C O N C AT( ) 几个数,则它将把它们转换成串,然后返回这些串的衔接,如:
? ? 假如作为表达式的构成部份调用C O N C AT( ),大概会举行进一步的范例转换.观察下列表达式及后来果:
? ? CONCAT(1, 2, 3) 产生串"1 2 3".表达式"1 2 3"/10 转换为1 2 3 / 1 0,因为除是一个算术运算符.这个表达式的后果的浮点情势为1 2 . 3,但REPEAT( ) 需求整数的反复计数值,所以举行整除得1 2.然后,REPEAT (‘X’, 12) 产生一个含有1 2个‘X’ 字符的后果串.普通原则是,MySQL 尽大概将值转换为表达式所需求的范例,尽大概避免由于值的范例不对而招致错误.按照上下文, MySQL 将在三种通用范例(数、串或日期与时间)之间举行值的转换.但是,值不能老是可以从一种范例转为另一种范例.假如被转换值不是给定范例的合理值,则此转换失利.将如"a b c" 这样不像数的东西转换为数,则后果为0.将不像日期或时间的东西转换为日期或时间范例后果为该范例的"零"值.比方,将串"a b c" 转换为日期后果为"零"日期" 0 0 0 0 - 0 0 - 0 0".而任何值都可以处理为串,因此,普通将某个值转换为串不会产生问题.
? ? MySQL 也举行一些细小的范例转换.假如在整型环境中利用一个浮点值,此值将被转换,转换时举行四舍五入.也可以举行相反的工作;一个整数用作浮点数也不会有问题.除非其内容显示表示一个数,不然十六进制常数普通作为串处理.在串上下文中,每对十六进制数字转换为一个字符,后来果作为串.下面是一些转换的样例:
? ? 相同的注释原理也利用到对比上;除非与其对比的是一个数,不然十六进制常量按串对待,比方:
? ? 某些运算符可将操作数强迫转换为它们所要的范例,而不管操作数是什么范例.比方,算术运算符需求数,并按此对操作数举行转换,参考以下运算:
? ? MySQL 不对整个串举行探求一个数的查找;它只查看串的起始处.假如一个串不以数作为前导部份,其转换后果为0.
? ? 请注意,MySQL 的串到数的转换法则自3 . 2 3版今后已经改变了.在该版本从前,近似于数的串被转换为四舍五入的整数值.自3.23 版后,它们转换为浮点值,比方:
? ? 逻辑和位运算符比算术运算符要求更为严峻.它们不但但愿操作数为数,并且还要求是整数.这表示一个浮点数,如. 3,不被视为真,固然它是非零的;这是因为在转换为整数时,. 3已经转换为0了.在下面的表达式中,除非各操作数有一个至少为1 的值,不然各操作数不被认为是真.
? ? 这种转换也呈目前IF( ) 函数中,此函数要求第一个参数为整数.为了恰本地对浮点值举行测试,最好是操纵明确的对比.不然,小于1 的值将被认为是假,比方:
? ? 情势匹配运算符要求对串举行处理.这表示可将MySQL 的情势匹配运算符用于数,因为MySQL 会在试图举行的匹配中将它们转换成串.比方:
? ? 大小对比运算符("<"、"< ="、"="等等)是上下文相关的;即,它们按照操作数的范例求值.下面的表达式从数值上对操作数举行对比,因为操作符两边都是数.
2 < 11 | -> 1 |
"2" < "11" | -> 0 |
? ? 在下面的对比中,范例是混合的,因此,MySQL 按数对比它们.后果是两个表达式都为真:
? ? 在各个对比中,MySQL 按照下列法则对操作数举行转换:
? ? ■ 除了"< = >"运算符外,触及NULL 值的对比其值为N U L L(除NULL <=> NULL 为真外,"< = >"与"="相同).
? ? ■ 假如两个操作数都是串,则按串举行字典次序的对比.串对比操纵服务器上有效的字符集举行.
? ? ■ 假如两个操作数都为整数,则按整数举行数的对比.
? ? ■ 不与数举行对比的十六进制常量按二进制串举行对比.
? ? ■ 假如此中有一个操作数为TIMES TAMP 或DATETIME 值而另一个为常量,则按TIMES TAMP 值举行对比.这样做将使对比对ODBC 利用更好.
? ? ■ 不然,两个操作数将按浮点值举行数的对比.注意,这包含一个串与一个数举行对比的情形.此中串被转换为数,假如该串转换后不是一个数,则后果为0.比方,"1 4 . 3"转换为1 4 . 3,但"L 4 . 3" 转换为0.
? ? 1. 日期与时间的注释法则
? ? MySQL 按表达式的环境将串和数安闲地转换为日期和时间值,反之亦然.日期和时间值在数值上下文中转换为数;数在日期或时间上下文中转换为日期或时间.在将一个值赋予一个日期或时间列时,或在函数需求一个日期或时间值时,举行转换为日期或时间值的转换.假如表my_table 含有一个D ATE 列date _ col,下列语句是等价的:
? ? TO _ DAYS( ) 函数的参数在下面三个表达中为相同的值:
? ? 2. 测试并强迫举行范例转换
? ? 为了理解表达式中范例转换是怎样举行的,用mysql 程序公布一条对表达式求值的SELECT 语句以下:
? ? 正如您所想像的那样,笔者在撰写本章时,做了不少这种对比.测试表达式的求值关于诸如DELETE 或U P D ATE 这种改正记录的语句极其重要,因为需求保证只触及所需触及的行.查抄表达式的一个办法是,预先履行一条具有预备用于DELETE 或U P D ATE 语句的相同WHERE 子句,以考证该子句挑选的行是精确的.假定表my_table 具有一个含有下列值的CHAR 列char _ col:
? ? 本来的打算大约是想删除包含值"0 0" 的那两行.但实际作用是删除了全部的行.之所以这样是由于MySQL 的对比法则在起作用.char_col 为一个串列,但00 没有效引号括起来,因此,它被作为数对待了.按MySQL 的对比法则,触及一个串与一个数的对比按两个数的对比来求值.随着DELETE 查询的履行,char_col 的每个值被转换为0,"0 0"也被转换为0,因此,全部不近似数的串都转换成0.从而,关于每一行, WHERE 子句都为真,因此,DELETE 语句清空了该表.明显,这是一种在履行DELETE 前,应当用SELECT 语句对WHERE 子句举行测试的情形,这样将会示出表达式所挑选的行太多了.以下所示:
? ? 假如不能必定某个值的利用方法,可以操纵MySQL 的表达式求值机制将该值强迫转换为特定的范例:
? ? ■ 增添+ 0 或+ 0.0 到某项上以强迫转换到一个数值:
? ? 3. 超范围值或不法值的转换
? ? 超范围值或不法值的转换的基本原则为:无用输入,无用输出.假如不在存储日期前对其举行考证,那么大概会得到不喜好的东西.下面给出一些MySQL 处理超范围值或不符合值的普通原则,这些内容曾经在前面介绍过:
? ? ■ 关于数值或T I M E列,超越合理范围的值被剪裁为呼应取值范围的最接近的数值并作为后果值存储.
? ? ■ 关于非ENUM 或SET 的串列,太长的串被截为合适该列存储的最大长度的串.ENUM 或SET 列的赋值依靠于定义列时给出的合理值.假如赋予ENUM 列一个未作为列举成员给出的值,将会赋予一个错误成员(即,对应于零值成员的空串).假如赋予SET 列一个包含未作为调集成员给出的子串的值,那么,那些未作为调集成员给出的子串将被删除,并将剩余成员构成的值赋给该列.
? ? ■ 关于日期或时间列,不法值被转换为该范例得当的"零"值(参阅表2 - 11).关于非TIME 的日期和时间列,超越取值范围的值可转换为"零"值、N U L L或某种其他的值(换句话说,后果是不可意料的).
? ? 这些转换都将作为A LTER TA B L E、LOAD DATA、U P D ATE 和多行I N S E RT 语句的告诫信息报告.在mysql 客户机中,这些信息显示在查询报告的状况行上.在编程语言中,可通过某些其他手段获得这个信息.假如利用的是MySQL C API,那么可调用mysql_info( ) 函数来得到这个信息.关于Perl DBI API,可操纵数据库衔接的mysql_info 属性.所供应的这个信息是告诫信息的次数计数.为了知道更改了哪些行,可公布一条SELECT ... INTOOUTFILE 查询,并将后果与原始行举行对比.
以上是“MySQL数据库技术(10)[MySQL防范]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |