马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
你碰到的问题可能已经在社区中被别的人已经问过,即使没有MySQL学习教程,你也可以提出问题或通过Google来搜索答案。社区的相关负责人士:“MySQL社区是活跃、友好和内容渊博的。”
2.4表达式求值和范例转换
MySQL同意编写包含常量、函数挪用和表列援用的表达式。这些值可使用分歧范例的运算符举行组合,诸如算术运算符或对照运算符。表达式的项可用圆括号来分组。表达式在SELECT语句的列选择列表和WHERE子句中呈现得最为频仍,以下所示:
所选择的每列给出了一个表达式,如WHERE子句中所示的那样。表达式也呈现在DELETE和UPDATE语句的WHERE子句中,和呈现在INSERT语句的VALUES()子句中。
在MySQL碰到一个表达式时,它对其求值得出了局。比方,(4*3)/(4-2)求值得6。表达式求值大概触及范例转换。比方,MySQL在数960821用于必要日期值的情况时,将其转换为日期“1996-08-21”。本节会商如何编写MySQL的表达式,和在表达式求值中MySQL所利用的范例转换划定规矩。每一个MySQL的运算符都先容过了,但MySQL有那末多的函数,我们只打仗过几个。每一个运算符和函数的进一步先容可参阅附录C。
2.4.1撰写表达式
表达式能够只是一个复杂的常量,如:
0数值常量
“abc”串常量
表达式能够举行函数挪用。有的函数必要参数(圆括号中有值),而有的不必要。多个参数应当用逗号分开。在挪用一个函数时,参数中间能够有空格,但在函数名与圆括号间不克不及有空格。上面是一些函数例子:
NOW()无参数函数
STRCMP(“abc”,“def”)有两个参数的函数
STRCMP(“abc”,“def”)参数中间有空格是正当的
STRCMP(“abc”,“def”)函数名后跟空格是分歧法的
假如函数名后有一个空格,MySQL的剖析程序大概会将函数名注释为一个列名(函数名不是保存字,假如必要的话,可将它们用作列名)。其了局是呈现一个语法毛病。表达式中可以使用表列。最复杂的情况是,当某个列所属的表在高低文中是明白的,则可复杂地给出列名对该列举行援用。上面的每一个SELECT语句中唯一地出了一个表名,因而,列的援用无歧义:
假如利用哪一个表的列不明白,可在列名前加上表名。假如利用哪一个数据库中的表也不明白的话,可在表名前加上数据库名。假如只是但愿意义更分明,也能够在无歧义的高低文中使用这类更加详细的暗示情势,如:
总之,能够组合一切这些值以失掉更加庞大的表达式。
1.运算符的范例
MySQL有几品种型的运算符,可用来毗连表达式的项。算术运算符,如表2-15所示,一样平常包含加、减、乘、除和模运算符。在两个操纵数都是整数时,“+”、“-”和“*”算术运算用BIGINT(64位)整数值来完成。而在了局预期为一个整数时,“/”和“%”也是用BIGINT(64位)整数值来完成的。应当熟悉到,假如某个运算触及更年夜的值,如了局凌驾64位,其了局不成意料。
逻辑运算符如表2-16所示,对表达式举行估量以断定其为真(非零)或假(零)。MySQL包括有C作风的“&&”、“||”和“!”运算符,可交换AND、OR和NOT。要出格注重“||”运算符,ANSISQL指定“||”作为串联接符,但在MySQL中,它暗示一个逻辑或运算。假如实行上面的查询,则前往数0:
MySQL为举行运算,将“abc”和“def”转换为整数,且二者都转换为0,0与0举行或运算,了局为0。在MySQL中,必需用CONCAT(“abc”,“def”)来完成串的毗连。
位运算符如表2-17所示,完成按位“与”和“或”,个中了局的每位按两个操纵数的对应位的逻辑AND或OR求值。还能够举行位的左移或右移。位运算用BIGINT(64位)整数值举行。
对照运算符如表2-18所示,个中包含测试绝对巨细或数和串的按次的运算符,和完成形式婚配和测试NULL值的运算符。“<=>”运算符是MySQL独有的,在MySQL3.23版本中引进。
自MySQL3.23版本起,可以使用BINARY运转符,此运算符可用来将一个串转换为一个二进制串,这个串在对照中是辨别巨细写的。以下的第一个对照是不辨别巨细写的,但第二个和第三个对照是辨别巨细写的:
没有响应的NOTBINARY盘算。假如但愿使一个列既能在辨别巨细写又能在不辨别巨细写的情况中利用,则应当使用不辨别巨细写的列并对但愿辨别巨细写的对照利用BINARY。关于使用二进制串范例(CHARBINARY、VARCHARBINARY和BLOB范例)界说的列,其对照老是辨别巨细写的。为了对如许的列范例完成不辨别巨细写的对照,可使用UPPER()或LOWER()来转换成不异的巨细写:
关于不辨别巨细写的串对照,有大概把多个字符以为是相称的,这取决于所用的字符集。比方“e”和“é”关于对照和排序操纵多是不异的。二进制(辨别巨细写)对照使用字符的ASCII值来完成。
形式婚配同意查找值而不用给出准确的间接值。MySQL使用LIKE运算符和通配符“%”(婚配恣意的字符序列)和“_”(婚配恣意单个字符),供应SQL的形式婚配。MySQL还基于相似于诸如grep、sed和vi等UNIX程序中所用的REGEXP运算符和扩大正轨表达式,供应形式婚配。为了完成形式婚配,必需利用这些形式婚配运算符中的某一个;不克不及利用“=”。为了举行相反的形式婚配,可以使用NOTLIKE或NOTREGEXP。
除利用的形式运算符和形式字符分歧外,这两种形式婚配还在以下主要的方面存在差别:
■除非最少有一个操纵数为二进制串,不然LIKE是不辨别巨细写的。REGEXP是辨别巨细写的。(在MySQL3.23.4今后的版本中,除非最少有一个操纵数是二进制串,不然REGEXP是不辨别巨细写的。)
■仅当全部串婚配,SQL才是形式婚配的。仅当响应的形式在串中某一处呈现,正轨表达式才婚配。用于LIKE运算符的形式能够包含“%”和“_”通配符。比方,形式“Frank%”与任何故“Frank”开端的串婚配:
通配符“%”与任何串婚配,个中包含与空字符序列婚配,因而“Frank%”与“Frank”婚配:
这也暗示形式“%”与任何串婚配,个中包含与空串婚配。可是,“%”不与NULL婚配。现实上,具有NULL操纵数的任何形式婚配都将失利:
MySQL的LIKE运算符是不辨别巨细写的,除非它最少有一个操纵数是二进制串。因而,缺省时“Frank%”与串“Frankly”和“frankly”婚配,但在二进制对照中,它只与个中之一婚配:
这分歧于ANSISQL的LIKE运算符,它是辨别巨细写的。通配符可在形式中任何中央给出。“%bert”与“Englebert”、“Bert”和“Albert”婚配。“%bert%”也与一切这些串婚配,并且还与如像“Berthold”、“Bertram”、和“Alberta”如许
的串婚配。LIKE所同意的另外一个通配符是“_”,它与单个字符婚配。“__”与三个字符的串婚配。“c_t”与“cat”、“cut”乃至“c_t”婚配(由于“_”与本身婚配)。为了关失落“%”或“_”的特别寄义,与这些字符的间接实例相婚配,必要在它们后面安排一个斜杠(“\%”或“\_”),如:
MySQL的另外一种情势的形式婚配利用了正轨表达式。运算符为REGEXP而不是LIKE(RLIKE为REGEXP的同义词)。最经常使用的正轨表达式形式字符以下:‘.’与恣意单个字符婚配:
‘[...]’与方括号中恣意字符婚配。可列出由短划线‘-’分开的局限端点指定一个字符局限。为了否认这类区间的意义(即与未列出的任何字符婚配),指定‘^’作为该区间的第一个字符便可:
‘*’暗示“与其后面字符的恣意数量的字符婚配”,因而,如‘x*’与恣意数量的‘x’字符婚配,比方:
“恣意数量”包含0个实例,这也就是为何第二个表达式婚配乐成的缘故原由。‘^pat’和‘pat$’流动了一种形式婚配,从而形式pat只在它呈现在串的前头时婚配,而‘^pat$’只在pat婚配全部串时婚配,比方:
REGEXP形式可从某个表列中掏出,固然假如该列包括几个分歧的值时,如许做比常量形式慢。每当列值变动时,必需对形式举行反省并转换成外部情势。MySQL的正轨表达式婚配另有一些特别的形式字符。要懂得更具体信息请参阅附录C。
2.运算符的优先级
当求一个表达式的值时,起首检察运算符以决意运算的前后序次。有的运算符具有较高的优先级;比方,乘和除比加和减的优先级更高。上面的两个表达式是等价的,由于“*”和“/”先于“+”和“-”盘算:
上面列出了运算符的优先级,从高到低。列在统一行中的运算符具有不异的优先级。优先级较高的运算符在优先级较低的运算符之前求值。
可用圆括号来疏忽运算符的优先级并改动表达式的求值按次,如:
3.表达式中的NULL值
请注重,在表达式中利用NULL值时,其了局有大概呈现不测。以下原则将有助于制止出成绩。假如将NULL作为算术运算或位运算符的一个操纵数,其了局为NULL:
假如将NULL用于逻辑运算符,NULL被以为是假:
NULL作为恣意对照运算符的操纵数,除<=>、ISNULL和ISNOTNULL运算符(它们是专门扩大来处置NULL值的)外,将发生一个NULL了局。如:
假如给函数一个NULL参数,除那些处置NULL参数的函数外,一样平常前往一个NULL了局。比方,IFNULL()可以处置NULL参数并得当地前往真或假。STRCMP()希冀一个非NULL的参数;假如它发明传给它的是一个NULL参数,则前往NULL而不是真或假。在排序操纵中,NULL值被回到一同。在升序排序中,NULL将排在一切非NULL值之前(包含空串),而在降序排序中,NULL将排在一切非NULL值以后。
2.4.2范例转换
MySQL依据所实行的操纵范例,主动地举行大批的范例转换,任什么时候候,只需将一个范例的值用于必要另外一范例值的场所,就会举行这类转换。上面是必要举行范例转换的缘故原由:
■操纵数转换为合适于某种运算符求值的范例。
■函数参数转换为函数所需的范例。
■转换某个值以便赋给一个具有分歧范例的表列。以下表达式触及范例转换。它由加运算符“+”和两个操纵数1和“2”构成:
1+"2"
个中操纵数的范例分歧,一个是数,另外一个是串,因而,MySQL对个中之一举行转换以便使它们两个具有不异的范例。可是应当转换哪个呢?由于,“+”是一个数值运算符,以是MySQL但愿操纵数为数,因而,将串“2”转换为数2。然后求此表达式的值得出3。再举一例。CONCAT()函数毗连串发生一个更长的串作为了局。为了完成此事情,它将参数注释为串,而不论参数实践是何范例。假如传送给CONCAT()几个数,则它将把它们转换成串,然后前往这些串的毗连,如:
假如作为表达式的构成部分挪用CONCAT(),大概会举行进一步的范例转换。考查以下表达式及其了局:
CONCAT(1,2,3)发生串“123”。表达式“123”/10转换为123/10,由于除是一个算术运算符。这个表达式的了局的浮点情势为12.3,但REPEAT()必要整数的反复计数值,以是举行整除得12。然后,REPEAT(‘X’,12)发生一个含有12个‘X’字符的了局串。一样平常准绳是,MySQL只管将值转换为表达式所必要的范例,只管制止因为值的范例不合错误而招致毛病。依据高低文,MySQL将在三种通用范例(数、串或日期与工夫)之间举行值的转换。可是,值不克不及老是能够从一品种型转为另外一品种型。假如被转换值不是给定范例的正当值,则此转换失利。将如“abc”如许不像数的器材转换为数,则了局为0。将不像日期或工夫的器材转换为日期或工夫范例了局为该范例的“零”值。比方,将串“abc”转换为日期了局为“零”日期“0000-00-00”。而任何值都能够处置为串,因而,一样平常将某个值转换为串不会发生成绩。
MySQL也举行一些巨大的范例转换。假如在整型情况中利用一个浮点值,此值将被转换,转换时举行四舍五进。也能够举行相反的事情;一个整数用作浮点数也不会有成绩。除非其内容显现暗示一个数,不然十六进制常数一样平常作为串处置。在串高低文中,每对十六进制数字转换为一个字符,其了局作为串。上面是一些转换的样例:
不异的注释道理也使用到对照上;除非与其对照的是一个数,不然十六进制常量按串看待,比方:
某些运算符可将操纵数强迫转换为它们所要的范例,而不论操纵数是甚么范例。比方,算术运算符必要数,并按此对操纵数举行转换,参考以下运算:
MySQL不合错误全部串举行寻觅一个数的查找;它只检察串的肇端处。假如一个串不以数作为前导部分,其转换了局为0。
请注重,MySQL的串到数的转换划定规矩自3.23版今后已改动了。在该版本之前,相似于数的串被转换为四舍五进的整数值。自3.23版后,它们转换为浮点值,比方:
逻辑和位运算符比算术运算符请求更加严厉。它们不但但愿操纵数为数,并且还请求是整数。这暗示一个浮点数,如.3,不被视为真,固然它长短零的;这是由于在转换为整数时,.3已转换为0了。鄙人面的表达式中,除非各操纵数有一个最少为1的值,不然各操纵数不被以为是真。
这类转换也呈现在IF()函数中,此函数请求第一个参数为整数。为了得当地对浮点值举行测试,最好是使用明白的对照。不然,小于1的值将被以为是假,比方:
形式婚配运算符请求对串举行处置。这暗示可将MySQL的形式婚配运算符用于数,由于MySQL会在试图举行的婚配中将它们转换成串。比方:
巨细对照运算符(“<”、“<=”、“=”等等)是高低文相干的;即,它们依据操纵数的范例求值。上面的表达式从数值上对操纵数举行对照,由于操纵符双方都是数。
2<11->1上面的表达式触及串对照,由于其双方的操纵数都是串:
"2"<"11"->0
鄙人面的对照中,范例是夹杂的,因而,MySQL按数对照它们。了局是两个表达式都为真:
在各个对照中,MySQL依据以下划定规矩对操纵数举行转换:
■除“<=>”运算符外,触及NULL值的对照其值为NULL(除NULL<=>NULL为真外,“<=>”与“=”不异)。
■假如两个操纵数都是串,则按串举行字典按次的对照。串对照使用服务器上无效的字符集举行。
■假如两个操纵数都为整数,则按整数举行数的对照。
■不与数举行对照的十六进制常量按二进制串举行对照。
■假如个中有一个操纵数为TIMESTAMP或DATETIME值而另外一个为常量,则按TIMESTAMP值举行对照。如许做将使对照对ODBC使用更好。
■不然,两个操纵数将按浮点值举行数的对照。注重,这包含一个串与一个数举行对照的情形。个中串被转换为数,假如该串转换后不是一个数,则了局为0。比方,”14.3”转换为14.3,但“L4.3”转换为0。
1.日期与工夫的注释划定规矩
MySQL按表达式的情况将串和数自在地转换为日期和工夫值,反之亦然。日期和工夫值在数值高低文直达换为数;数在日期或工夫高低文直达换为日期或工夫。在将一个值付与一个日期或工夫列时,或在函数必要一个日期或工夫值时,举行转换为日期或工夫值的转换。假如表my_table含有一个DATE列date_col,以下语句是等价的:
TO_DAYS()函数的参数鄙人面三个表达中为不异的值:
2.测试并强迫举行范例转换
为了懂得表达式中范例转换是如何举行的,用mysql程序公布一条对表达式求值的SELECT语句以下:
正如您所想像的那样,笔者在撰写本章时,做了很多这类对照。测试表达式的求值关于诸如DELETE或UPDATE这类修正纪录的语句极其主要,由于必要包管只触及所需触及的行。反省表达式的一个举措是,事后实行一条具有筹办用于DELETE或UPDATE语句的不异WHERE子句,以考证该子句选择的行是准确的。假设表my_table具有一个含有以下值的CHAR列char_col:
本来的盘算也许是想删除包括值“00”的那两行。但实践感化是删除一切的行。之以是如许是因为MySQL的对照划定规矩在起感化。char_col为一个串列,但00没有效引号括起来,因而,它被作为数看待了。按MySQL的对照划定规矩,触及一个串与一个数的对照按两个数的对照来求值。跟着DELETE查询的实行,char_col的每一个值被转换为0,”00”也被转换为0,因而,一切不相似数的串都转换成0。从而,关于每行,WHERE子句都为真,因而,DELETE语句清空了该表。明显,这是一种在实行DELETE前,应当用SELECT语句对WHERE子句举行测试的情形,如许将会示出表达式所选择的行太多了。以下所示:
假如不克不及一定某个值的利用体例,能够使用MySQL的表达式求值机制将该值强迫转换为特定的范例:
■增添+0或+0.0到某项上以强迫转换到一个数值:
3.超局限值或不法值的转换
超局限值或不法值的转换的基础准绳为:无用输出,无用输入。假如不在存储日期前对其举行考证,那末大概会失掉不喜好的器材。上面给出一些MySQL处置超局限值或分歧适值的一样平常准绳,这些内容已经在后面先容过:
■关于数值或TIME列,超越正当局限的值被剪裁为响应取值局限的最靠近的数值并作为了局值存储。
■关于非ENUM或SET的串列,太长的串被截为合适该列存储的最年夜长度的串。ENUM或SET列的赋值依附于界说列时给出的正当值。假如付与ENUM列一个未作为列举成员给出的值,将会付与一个毛病成员(即,对应于零值成员的空串)。假如付与SET列一个包括未作为汇合成员给出的子串的值,那末,那些未作为汇合成员给出的子串将被删除,并将残剩成员组成的值赋给该列。
■关于日期或工夫列,不法值被转换为该范例得当的“零”值(参阅表2-11)。关于非TIME的日期和工夫列,超越取值局限的值可转换为“零”值、NULL或某种其他的值(换句话说,了局是不成意料的)。
这些转换都将作为ALTERTABLE、LOADDATA、UPDATE和多行INSERT语句的告诫信息呈报。在mysql客户机中,这些信息显现在查询呈报的形态行上。在编程言语中,可经由过程某些其他手腕获得这个信息。假如利用的是MySQLCAPI,那末可挪用mysql_info()函数来取得这个信息。关于PerlDBIAPI,可使用数据库毗连的mysql_info属性。所供应的这个信息是告诫信息的次数计数。为了晓得变动了哪些行,可公布一条SELECT...INTOOUTFILE查询,并将了局与原始行举行对照
珍贵的资金可以用于其他业务的启动,诸如市场、广告或调研和开发等。 |