大神们为什么调用函数就可以正确输出java 字符串调用函数,不掉用函数用同样方法就存在错误???大神求解

MySQL &&&&最新内容
MySQL &&&&相关内容《IOS_C语言》函数分类、函数声明和定义、函数调用、形参实参、函数嵌套调用 - CSDN博客
《IOS_C语言》函数分类、函数声明和定义、函数调用、形参实参、函数嵌套调用
一:函数分类
函数是指具有特定的功能代码的代码段,后面只要想要使用该功能只要调用函数就可以,可以减少代码的重复性,效率自然也会高很多。
函数的分类:
(1)库函数:系统提供好的函数,例如printf()输出函数;输入函数scanf();strlen()求字符串长度的函数;strcat()拼接函数;strcmp()比较函数;strcpy()赋值函数,这些均是适用于字符串数组的操作的库函数。
(2)自定义函数(开发者自主定义的函数)
根据功能需要定义函数,可以有返回值,也可以没有返回值,类型也是必须的。
二:函数声明和定义
声明:放于xxx.h文件,可以放结构体定义、函数定义的类型修饰符+函数名+(形参列表)+分号“;”
定义:放于xxx.m文件,但不是main.m文件
调用:放于main.m文件,在头文件还要引入xxx.h文件,才能实现调用函数
返回值类型(void/int/char/float```)函数名(形式参数列表)
&& return 返回值;
//这里的返回值,也成为函数的值,只能通过return语句返回给主函数,并且一个函数最多只能有一个返回值,函数即使没有返回值,也可以只是一个或者return 0;来结束函数的执行,从而返回到主函数里面。return后面的语句不会再执行。
无参函数举例:
void hello(void)
&& printf(&Hello word!&);
int peopleCount(void)//无参数,有返回值
& return 33;
有参数函数举例
int Max(int a,int b){//有参数,有返回值
&& return a&b?a:b;
void&& printNumber(int x)//有参数,无返回值,冒泡排序也是一个典型的有参数无返回值的函数。
& printf(“number is %d”,x);在函数里面就会显示出结果来。
三:函数调用
(1)有返回值的,直接定义一个跟函数的类型相同的变量来接收函数调用后的结果
int result=getNmuner(str);//计算一个字符串的长度
如://1、定义函数int sumValue(int n):计算1到n的和
int sumValue(int n)
&&& int sum=0;
&&& for (int i=0; i&=n; i++) {
&&&&&&& sum+=i;
//1、调用函数int sumValue(int n):计算1到n的和
//&&& int sum=sumValue(5);
//&&& printf(&sum=%d&,sum);
//&&& printf(&\n&);
(2)没有返回值的,则直接调用函数名,并且传实参进去就可以了
sortArray(str,4);//冒泡排序
//练习3:定义冒泡排序(无需返回值)的函数
void sortArray(int a[],int n)//这里void表示执行功能,不返回任何东西
//形参传的是(数组名+[]即&a[]&,数组元素个数)
//实参传送的是(数组名aray,数组元素个数)
&&& for (int i=0; i&n-1; i++) {
&&&&&&& for (int j=0; j&n-1-i; j++) {
&&&&&&&&&&& if (a[j]&a[j+1]) {
&&&&&&&&&&&&&&& int temp=a[j];
&&&&&&&&&&&&&&& a[j]=a[j+1];
&&&&&&&&&&&&&&& a[j+1]=
&&&&&&&&&&& }
调用冒泡排序:
&&& //练习3:
&&& int array[]={1,2,3,4,5,6,3,2,4,5};
&&& unsigned int count=sizeof(array)/sizeof(int);//也就是sizeof(array)/4,因为sizeof()是计算字符字节数的,而int型恰好是4个字节,而char是一个字节的。
&& //int b[10]=sortArray(int a[],count);//错,因为是、void型的函数定义,无返回值的,则无需b[]来接受
&&& sortArray(array,count);
&&& //形参传的是(数组名+[]即&a[]&,数组元素个数)
&&& //实参传送的是(数组名aray,数组元素个数)
&&& printf(&排序后:\n&);
&&& for (int i=0; i& i++) {
&&&&&&&& printf(&array[%d]=%d\n&,i,array[i]);
四:形参实参
在定义函数是,函数名(这里放的是形参)
在调用函数时,函数名(这里放的是实参)
在函数调用时,形参会拷贝实参的内容,传递参数是给函数传递信息的一种方法
需要注意的是数组作为参数时
函数定义时,如冒泡排序,void sortArray(char str[],int count)这里数组的类型修饰符char 数组名str 以及数组的标志[ ],都需要传进去,整型的count 也需要传;
函数调用时,如冒泡排序,sortArray(str,5);这里传的实参里,则只需要数组名str,以及实参5就可以调用了
五:函数嵌套调用
在定义函数时,调用已经定义好的函数,叫做函数嵌套调用
//练习4(函数嵌套调用)
//求两个数的最?大值!
//!求三个数的最?大值!
//!求四个数的最?大值!
int getTwoMax(int a,int b)
&&& int max=a&b?a:b;
int getThreeMax(int a,int b,int c)
&&& int max=getTwoMax(a, b);
&&& max=getTwoMax(max, c);
int getFourMax(int a,int b,int c,int d)
&&& int max=getThreeMax(a,b, c);
&&& max=getTwoMax(max, d);
int getFiveMax(int a,int b,int c,int d,int e)
&&& int max=getFourMax(a, b, c, d);
&&& max=getTwoMax(max, e);
六:函数的递归调用
递归调用,是指函数调用本身
//计算s = (1*1)!+(2*2)! + (3*3)!
//1、整型数的平?方sql
//2、?一个整型数的阶乘factorial
int sql(int a)
&&& int result=a*a;
//int factorial(int n)//方法1用for循环实现求阶乘
//&&& int result=1;
//&&& for (int i=1; i&=n; i++) {
//&&&&&&& result*=i;
int factorial(int n)//方法2用递归实现求阶乘
&&& //if条件是递归的出口,不然是死循环
&&& if(n&=1){//负数没有阶乘,n=0时,0的阶乘是1,1的阶乘也是1
&&&&&&& return 1;
&&& return factorial(n-1)*n;//如n=5,5Xfactorial(4)=5X4Xfactorial(3)=5X4X3Xfactorial(2)=5X4X3X2Xfactorial(1)=5X4X3X2X1
int getSqlFact(int n){
&&& int s=0;
//&&& int a=0;
&&& for (int i=1; i&=n; i++) {
//&&&&&&& a=sql(i);//方法一,拆分先求平方,再求阶乘
//&&&&&&& s+=factorial(a);
&&&&&&& s+=factorial(sql(i));//函数的嵌套调用,再调用,方法二
七:变量的作用域
局部变量(在各个函数领域内的),只作用于本函数体内
全局变量(在整个主函数内有效,甚至是定义在头文件和main函数体之间的,则作用于所有的代码,但是局部变量的优先级高于全局变量)
int number1=1;//全局变量,并且只能在它以下的代码使用,并且如果下面局部变量有重名的,则局部变量会优先使用,如下面的number1=2,输出是2.
int main(int argc, const char * argv[]){
&&& int number1=2;//局部变量
&&& printf(&number1=%d\n&,number1);
输出的结果是number1=2的
课上代码:
#import &Foundation/Foundation.h&
//.h文件放的全是声明
//函数调用,函数定义放于头文件则可以不用函数声明,如果是放于主函数后面则必须在头文件声明,如下:记得加上“;”
int sum(int a);
//求最大值
int max_value(int a,int b);
//求累计和
int sumValue(int n);
//计算该年的那一日
int dayOfYear(int year,int month,int day);
//求三个数中的中间值
int middle(int a,int b,int c);
//统计一个数的位数
int number(unsigned int n);
int getsum(int a,int b);
int getjian(int a,int b);
//求两个数的乘积
int getcheng(int a,int b);
//求两个数的商(除法)
float getchu(int a,int b);
//冒泡排序
void sortArray(int a[],int n);//冒泡排序无需返回值,则为void,并且传个数组名以及标识a[],以及数组元素个数n
//求两个数的最大值
int getTwoMax(int a,int b);
//求三个数的最大值
int getThreeMax(int a,int b,int c);
//求四个数的最大值
int getFourMax(int a,int b,int c,int d);
//求五个数的最大值
int getFiveMax(int a,int b,int c,int d,int e);
//求一个数的平方
int sql(int a);
//求一个数的阶乘
int factorial(int n);
//求一个数的平方的阶乘
int getSqlFact(int n);
#import &Operator.h&
//函数定义
//定义求和函数(返回和,并且返回值在主函数里面有用,如果有函数声明则可以防于后面)
int sum(int a){
&&& int sum=0;
&&& sum+=a;
//定义取最大值,并且最大值在主函数中有用,
int max_value(int a,int b)
&&& int max=0;
&&& max=a&b?a:b;
&&& //printf(&%d&,max);//这种就只是显示,max在主函数中并没有用。
&&& //return 0;
//课上练习1
//1、编写函数int sumValue(int n):计算1到n的和
int sumValue(int n)
&&& int sum=0;
&&& for (int i=0; i&=n; i++) {
&&&&&&& sum+=i;
//2、编写函数dayOfYear(year, mouth,day),使得函数返回由这三个参数确定的那?一天是?一年中的第?几天
int dayOfYear(int year,int month,int day)
&&& int date=0;
&&& int TodayY
&&& printf(&Please input TodayYear:&);
&&& scanf(&%d&,&TodayYear);
&&& //判断合法性
&&& for (;i++ ) {
&&&&&&& printf(&Please input a date:&);
&&&&&&& scanf(&%d%d%d&,&year,&month,&day);
&&&&&&& if (year&=TodayYear) {
&&&&&&&&&&& if (year%400==0||(year%4==0&&year%10!=0)) {
&&&&&&&&&&&&&&& if (month==2) {
&&&&&&&&&&&&&&&&&&& if (day&=1&&day&=29) {
&&&&&&&&&&&&&&&&&&&&&&& printf(&您输入的是润年的2月份,输入的日期合法\n&);
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&& }else{
&&&&&&&&&&&&&&&&&&&&&&& printf(&您输入的是润年的2月份,输入的日期不合法!请输入的日期范围是1~29\n&);
&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&& }else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){
&&&&&&&&&&&&&&&&&&& if (day&=1&&day&=31) {
&&&&&&&&&&&&&&&&&&&&&&& printf(&您输入的是大月份,输入的日期合法\n&);
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&& }else{
&&&&&&&&&&&&&&&&&&&&&&& printf(&您输入的是大月份,输入的日期不合法!请输入的日期范围是1~31\n&);
&&&&&&&&&&&&&&&&&&&&&& &
&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&& }else if(month==4||month==6||month==9||month==11){
&&&&&&&&&&&&&&&&&&& if (day&=1&&day&=30) {
&&&&&&&&&&&&&&&&&&&&&&& printf(&您输入的是小月份,输入的日期合法\n&);
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&& }else{
&&&&&&&&&&&&&&&&&&&&&&& printf(&您输入的是小月份,输入的日期不合法!请输入的日期范围是1~30\n&);
&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&& }else{
&&&&&&&&&&&&&&&&&&& printf(&请输入合法的月份,范围1~12月\n&);
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&& &
&&&&&&&&&&& }else {
&&&&&&&&&&&&&&& if (month==2) {
&&&&&&&&&&&&&&&&&&& if (day&=1&&day&=28) {
&&&&&&&&&&&&&&&&&&&&&&& printf(&您输入的是平年的2月份,输入的日期合法\n&);
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&& }else{
&&&&&&&&&&&&&&&&&&&&&&& printf(&您输入的是平年的2月份,输入的日期不合法!请输入的日期范围是1~28\n&);
&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&& }else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){
&&&&&&&&&&&&&&&&&&& if (day&=1&&day&=31) {
&&&&&&&&&&&&&&&&&&&&&&& printf(&您输入的是大月份,输入的日期合法\n&);
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&& }else{
&&&&&&&&&&&&&&&&&&&&&&& printf(&您输入的是大月份,输入的日期不合法!请输入的日期范围是1~31\n&);
&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&& }else if(month==4||month==6||month==9||month==11){
&&&&&&&&&&&&&&&&&&& if (day&=1&&day&=30) {
&&&&&&&&&&&&&&&&&&&&&&& printf(&您输入的是小月份,输入的日期合法\n&);
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&& }else{
&&&&&&&&&&&&&&&&&&&&&&& printf(&您输入的是小月份,输入的日期不合法!请输入的日期范围是1~30\n&);
&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&& }else{
&&&&&&&&&&&&&&&&&&& printf(&请输入合法的月份,范围1~12月\n&);
&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&& &
&&&&&&&&&&& }
&&&&&&&&&& &
&&&&&&& }else{
&&&&&&&&&&& printf(&请输入合法的年份,必须小于等于今年%d\n!&,TodayYear);
&&& int a[][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},
&&&&&&& {0,31,29,31,30,31,30,31,31,30,31,30,31}};
&&& if (month==1&&day&0&&day&31) {
&&&&&&& date=
&&& }else if(month&1&&month&13){
&&&&&&& for (int i=1; i& i++) {
&&&&&&&&&&& if (year%400==0||(year%4==0&&year%100!=0)) {
&&&&&&&&&&&&&&& date+=a[0][i];
&&&&&&&&&&& }else{
&&&&&&&&&&&&&&& date+=a[1][i];
&&&&&&&&&&& }
&&&&&&& date+=
&&& }else{
&&&&&&& printf(&error!&);
&&& printf(&date=%d\n&,date);
//3、编写函数,返回三个整数的中间数
int middle(int a,int b,int c)//或者命名getMidValue,驼峰命名法首个单词的首字母小写,其他单词首字母大写
&&& int max=a&b?a:b;
&&& max=max&c?max:c;
&&& int min=a&b?a:b;
&&& min=min&c?min:c;
&&& int mid=a+b+c-max-
//4、编写函数,返回正整数n中的数字的个数
int number(unsigned int n)
&&& int count=1;
&&& while (n/10!=0) {
&&&&&&& n=n/10;
&&&&&&& count++;
//练习2:创建?一对?文件:operator.h& operator.m实4个函数,分别求两个整型数的加、减、乘、除
int getsum(int a,int b)
&&& return a+b;
int getjian(int a,int b)
&&& return a-b;
int getcheng(int a,int b)
&&& return a*b;
float getchu(int a,int b)
&&& if(b!=0){
&&&&&&& return a/b*1.0;//由整型强制变成浮点型或者a/(float)b
&&& }else{
&&&&&&& printf(&除数不能为0!&);
&&&&&&& return -1;//表示程序出问题
//练习3:冒泡排序(无需返回值)
void sortArray(int a[],int n)
//形参传的是(数组名+[]即&a[]&,数组元素个数)
//实参传送的是(数组名aray,数组元素个数)
&&& for (int i=0; i&n-1; i++) {
&&&&&&& for (int j=0; j&n-1-i; j++) {
&&&&&&&&&&& if (a[j]&a[j+1]) {
&&&&&&&&&&&&&&& int temp=a[j];
&&&&&&&&&&&&&&& a[j]=a[j+1];
&&&&&&&&&&&&&&& a[j+1]=
&&&&&&&&&&& }
//练习4(函数嵌套调用)
//求两个数的最?大值!
//!求三个数的最?大值!
//!求四个数的最?大值!
int getTwoMax(int a,int b)
&&& int max=a&b?a:b;
int getThreeMax(int a,int b,int c)
&&& int max=getTwoMax(a, b);
&&& max=getTwoMax(max, c);
int getFourMax(int a,int b,int c,int d)
&&& int max=getThreeMax(a,b, c);
&&& max=getTwoMax(max, d);
int getFiveMax(int a,int b,int c,int d,int e)
&&& int max=getFourMax(a, b, c, d);
&&& max=getTwoMax(max, e);
//计算s = (1*1)!+(2*2)! + (3*3)!
//1、整型数的平?方sql
//2、?一个整型数的阶乘factorial
int sql(int a)
&&& int result=a*a;
//int factorial(int n)//方法1用for循环实现求阶乘
//&&& int result=1;
//&&& for (int i=1; i&=n; i++) {
//&&&&&&& result*=i;
int factorial(int n)//方法2用递归实现求阶乘
&&& //if条件是递归的出口,不然是死循环
&&& if(n&=1){//负数没有阶乘,n=0时,0的阶乘是1,1的阶乘也是1
&&&&&&& return 1;
&&& return factorial(n-1)*n;//如n=5,5Xfactorial(4)=5X4Xfactorial(3)=5X4X3Xfactorial(2)=5X4X3X2Xfactorial(1)=5X4X3X2X1
int getSqlFact(int n){
&&& int s=0;
//&&& int a=0;
&&& for (int i=1; i&=n; i++) {
//&&&&&&& a=sql(i);
//&&&&&&& s+=factorial(a);
&&&&&&& s+=factorial(sql(i));//递归调用,方法二
main.m文件
//& main.m
//& LessonC05
//& Created by lanou on 15/8/24.
//& Copyright (c) 2015年 lanou. All rights reserved.
#import &Foundation/Foundation.h&
#import&Operator.h&//导入声明的文件.h就可以了,并且要用“”双引号
//声明都放于.h文件,实现函数的定义放于.m文件,在main.m里面导入声明文件就可以了。#import&Operator.h&
int number1=1;//全局变量,并且只能在它以下的代码使用,并且如果下面局部变量有重名的,则局部变量会优先使用,如下面的number1=2,输出是2.
int main(int argc, const char * argv[]){
&&& int number1=2;//局部变量
&&& printf(&number1=%d\n&,number1);
&& //1、调用函数int sumValue(int n):计算1到n的和
//&&& int sum=sumValue(5);
//&&& printf(&sum=%d&,sum);
//&&& printf(&\n&);
&&& //2、调用函数dayOfYear(year, mouth,day),使得函数返回由这三个参数确定的那?一天是?一年中的第?几天
//&&& int date=dayOfYear();
//&&& printf(&date=%d&,date);
//&&& printf(&\n&);
&&&&& //3、编写函数,返回三个整数的中间数
//&&& int mid=middle(3,5,2);
//&&& printf(&mid=%d&,mid);
//&&& printf(&\n&);
&&& //4、函数调用,返回正整数n中的数字的个数
//&&& int count=number(1005);
//&&& printf(&count=%d&,count);
//&&& printf(&\n&);
&&& //练习2:创建?一对?文件:operator.h& operator.m实现4个函数,分别求两个整型数的加、减、乘、除
//&&& int he=getsum(6,2);
//&&& printf(&he=%d\n&,he);
//&&& int jian=getjian(6, 2);
//&&& printf(&jian=%d\n&,jian);
//&&& int cheng=getcheng(6, 2);
//&&& printf(&cheng=%d\n&,cheng);
//&&& float chu=getjian(6, 2);
//&&& printf(&chu=%f\n&,chu);
&&& //练习3:
&&& int array[]={1,2,3,4,5,6,3,2,4,5};
&&& unsigned int count=sizeof(array)/sizeof(int);//也就是sizeof(array)/4,因为sizeof()是计算字符字节数的,而int型恰好是4个字节,而char是一个字节的。
&& //int b[10]=sortArray(int a[],count);//错,因为是、void型的函数定义,无返回值的,则无需b[]来接受
&&& sortArray(array,count);
&&& //形参传的是(数组名+[]即&a[]&,数组元素个数)
&&& //实参传送的是(数组名aray,数组元素个数)
&&& printf(&排序后:\n&);
&&& for (int i=0; i& i++) {
&&&&&&&& printf(&array[%d]=%d\n&,i,array[i]);
&&& //练习4:
&&& //两个数求最大值
//&&& int maxValue1=getTwoMax(6, 2);
//&&& printf(&%d\n&,maxValue1);
//&&& //三个数求最大值
//&&& int maxValue2=getThreeMax(9,78,6);
//&&& printf(&%d\n&,maxValue2);
//&&& //四个数求最大值
//&&& int maxValue3=getFourMax(5,6,1,23);
//&&& printf(&%d\n&,maxValue3);
//&&& //五个数求最大值
//&&& int maxValue4=getFiveMax(56,24,45,345,3421);
//&&& printf(&%d\n&,maxValue4);
&&& //练习5(函数调用)
&&& ////计算s = (1*1)!+(2*2)! + (3*3)!
&&& //1、整型数的平?方sql
&&& //2、?一个整型数的阶乘factorial
//&&& printf(&please input a number:&);
//&&& scanf(&%d&,&n);
//&&& int result=getSqlFact(n);
//&&& printf(&result=%d\n&,result);
&&&& //函数
//&&& //函数的定义
//&& 返回值类型(void/int/char/foat....)函数名(形式参数列表)
//&&&&&&& 语句(功能段代码);
//&&&&&&& return 返回值;
//&&& 返回值类型:(void/int/char/foat....)
//&&&& void表示执行功能,不返回任何东西
&&& //课上练习:
&&& //&&& int max=max_value(4, 5);//函数调用:
&&& //&&& //返回值类型(void/int/char/foat....)函数名(实参)
&&& //&&& printf(&%d\n&,max);
&&& return 0;
本文已收录于以下专栏:
相关文章推荐
c语言中函数声明方式,以及相关的问题,通过实例讲解不同情况下构建函数产生的问题。
一般变量作函数参数,调用结束后,只改变了形式参数的值,实参不变。
指针变量作函数参数,调用结束后,不能改变实参指针变量的值但可以改变实参指针变量所指向变量的值。
很多初学者搞不明白子函数中什么时候可以改变实参值,什么时候不会改变。今天来具体分析下。
先来解释下实参和形参,所谓实参,就是通过主函数传递给子函数的变量。而子函数中用来接收变量的参数就称形参。如下:...
关于函数调用过程中的实参和形参问题
作者:张老师,华清远见嵌入式学院讲师。
C语言是一种面向过程的语言,它的程序执行过程是按逻辑顺序执行,在函数的函数体的定于位置与程序执行无关,该函数必须在程序执行过...
问:能否像下边这样用void **指针作为参数,使函数模拟按引用传递参数吗?
         void f(void **);
       &...
下面来看个例子,很简单的一个例子,但子函数有大量的形参(10个),以此来看看函数调用过程是如何做形参和实参的复制。
int fun(int n0,i...
1、问题描述
若已定义的函数有返回值,则以下关于该函数调用的叙述中错误的是( D
A)函数调用可以作为独立的语句存在
B)函数调用可以作为一个函数的实参
C)函数调用可以出现在表达...
day08 函数
什么是函数 :函数就是一段特殊功能的代码
函数 定义 的语法函数必须写在main函数的外面
数据类型 函数名称(参数列表)
形参:在被调函数形参表中的变量名、数组名,该过程在被调用前,没有为它们分配内存,其作用是说明自变量的类型和形态以及在过程中的作用。
形参可以是 合法变量名,数组名
实参:从主...
对于函数的默认实参,我们一般都是放在函数的声明中的,而在定义中并不指定默认实参:
在头文件中声明函数:
void func(int i = 0);
而在对应的源文件中实现函数...
他的最新文章
讲师:王禹华
讲师:宋宝华
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)MySQL中文参考手册- 7 MySQL 语言参考
<body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#101090" VLINK="#7030B0" class="p4"
MySQL中文参考手册
一个字符串是一个字符序列,由单引号(“'”)或双引号(“&”)字符(后者只有你不在ANSI模式运行)包围。例如:
'a string'
&another string&
在字符串内,某个顺序有特殊的意义。这些顺序的每一个以一条反斜线(“\”)开始,称为转义字符。MySQL识别下列转义字符:
一个ASCII 0 (NUL)字符。
一个新行符。
一个定位符。
一个回车符。
一个退格符。
一个单引号(“'”)符。
一个双引号(“&”)符。
一个反斜线(“\”)符。
一个“%”符。它用于在正文中搜索“%”的文字实例,否则这里“%”将解释为一个通配符。
一个“_”符。它用于在正文中搜索“_”的文字实例,否则这里“_”将解释为一个通配符。
注意,如果你在某些正文环境中使用“\%”或“\%_”,这些将返回字符串“\%”和“\_”而不是“%”和“_”。
有几种方法在一个字符串内包括引号:
一个字符串内用“'”加引号的“'”可以被写作为“''”。
一个字符串内用“&”加引号的“&”可以被写作为“&&”。
你可以把一个转义字符(“\”)放在引号前面。
一个字符串内用“&”加引号的“'”不需要特殊对待而且不必被重复或转义。同理,一个字符串内用“'”加引号的与“&”也不需要特殊对待。
下面显示的SELECT演示引号和转义如何工作:
mysql& SELECT 'hello', '&hello&', '&&hello&&', 'hel''lo', '\'hello';
+-------+---------+-----------+--------+--------+
| hello | &hello& | &&hello&& | hel'lo | 'hello |
+-------+---------+-----------+--------+--------+
mysql& SELECT &hello&, &'hello'&, &''hello''&, &hel&&lo&, &\&hello&;
+-------+---------+-----------+--------+--------+
| hello | 'hello' | ''hello'' | hel&lo | &hello |
+-------+---------+-----------+--------+--------+
mysql& SELECT &This\nIs\nFour\nlines&;
+--------------------+
+--------------------+
如果你想要把二进制数据插入到一个BLOB列,下列字符必须由转义序列表示:
ASCII 0。你应该用'\0'(一个反斜线和一个ASCII '0')表示它。
ASCII 92,反斜线。用'\\'表示。
ASCII 39,单引号。用“\'”表示。
ASCII 34,双引号。用“\&”表示。
如果你写C代码,你可以使用C API函数mysql_escape_string()来为INSERT语句转义字符。见。在 Perl中,你可以使用DBI包中的quote方法变换特殊的字符到正确的转义序列。见。
你应该在任何可能包含上述任何特殊字符的字符串上使用转义函数!
整数表示为一个数字顺序。浮点数使用“.”作为一个十进制分隔符。这两种类型的数字可以前置“-”表明一个负值。
有效整数的例子:
有效浮点数的例子:
一个整数可以在浮点上下文使用;它解释为等值的浮点数。
MySQL支持十六进制值。在数字上下文,它们表现类似于一个整数(64位精度)。在字符串上下文,它们表现类似于一个二进制字符串,这里每一对十六进制数字被变换为一个字符。
mysql& SELECT 0xa+0
mysql& select 0x5061756c;
十六进制字符串经常被ODBC使用,给出BLOB列的值。
NULL值意味着“无数据”并且不同于例如数字类型的0为或字符串类型的空字符串。见。
当使用文本文件导入或导出格式(LOAD DATA INFILE, SELECT
... INTO OUTFILE)时,NULL可以用\N表示。见。
数据库、表、索引、列和别名的名字都遵守MySQL同样的规则:
注意,从MySQL3.23.6开始规则改变了,此时我们引入了用'引用的标识符(数据库、表和列命名)(如果你以ANSI模式运行,&也将用于引用标识符)。
允许的字符
在一个目录名允许的任何字符,除了/.
在文件名中允许的任何字符,除了/或.
注意,除了以上,你在一个标识符中不能有ASCII(0)或ASCII(255)。
注意,如果标识符是一个限制词或包含特殊字符,当你使用它时,你必须总是用`引用它:
SELECT * from `select` where `select`.id & 100;
在 MySQL的先前版本,命名规则如下:
一个名字可以包含来自当前字符集的数字字母的字符和“_”和“$”。缺省字符集是ISO-8859-1
Latin1;这可以通过重新编译MySQL来改变。见。
一个名字可以以在一个名字中合法的任何字符开始。特别地,一个名字可以以一个数字开始(这不同于许多其他的数据库系统!)。然而,一个名字不能仅仅由数字组成。
你不能在名字中使用“.”,因为它被用来扩充格式,你能用它引用列(见下面)。
建议你不使用象1e这样的名字,因为一个表达式如1e+1是二义性的。它可以解释为表达式1e
+ 1或数字1e+1。
在MySQL中,你能使用下列表格的任何一种引用列:
来自于任意表的列col_name,用于包含该表的一个列的查询中
tbl_name.col_name
来自当前的数据库的表tbl_name的列col_name
db_name.tbl_name.col_name
行列col_name从表格tbl_name数据库db_name。这个形式在MySQL3.22或以后版本可用。
`column_name`
是一个关键词或包含特殊字符的列。
在一条语句的列引用中,你不必指定一个tbl_name或db_name.tbl_name前缀,除非引用会有二义性。例如,假定表t1和t2,每个均包含列c,并且你用一个使用t1和t2的SELECT语句检索c。在这种情况下,c有二义性,因为它在使用表的语句中不是唯一的,因此你必须通过写出t1.c或t2.c来指明你想要哪个表。同样,如果你从数据库db1中一个表t和在数据库db2的一个表t检索,你必须用db1.t.col_name和db2.t.col_name引用这些数据表的列。
句法.tbl_name意味着在当前的数据库中的表tbl_name,该句法为了ODBC的兼容性被接受,因为一些ODBC程序用一个“.”字符作为数据库表名的前缀。
在MySQL中,数据库和表对应于在那些目录下的目录和文件,因而,内在的操作系统的敏感性决定数据库和表命名的大小写敏感性。这意味着数据库和表名在Unix上是区分大小写的,而在Win32上忽略大小写。
注意:在Win32上,尽管数据库和表名是忽略大小写的,你不应该在同一个查询中使用不同的大小写来引用一个给定的数据库和表。下列查询将不工作,因为它作为my_table和作为MY_TABLE引用一个表:
mysql& SELECT * FROM my_table WHERE MY_TABLE.col=1;
列名在所有情况下都是忽略大小写的。
表的别名是区分大小写的。下列查询将不工作,:
因为它用a和A引用别名:
mysql& SELECT col_name FROM tbl_name AS a
WHERE a.col_name = 1 OR A.col_name = 2;
列的别名是忽略大小写的。
MySQL支持线程特定的变量,用@variablename句法。一个变量名可以由当前字符集的数字字母字符和“_”、“$”和“.”组成。缺省字符集是ISO-8859-1
Latin1;这可以通过重新编译MySQL改变。见。
变量不必被初始化。缺省地,他们包含NULL并能存储整数、实数或一个字符串值。当线程退出时,对于一个线程的所有变量自动地被释放。
你可以用SET句法设置一个变量:
SET @variable= { integer expression | real expression | string expression }
[,@variable= ...].
你也可以用@variable:=expr句法在一个表达式中设置一个变量:
select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
+----------------------+------+------+------+
| @t1:=(@t2:=1)+@t3:=4 | @t1
+----------------------+------+------+------+
+----------------------+------+------+------+
(这里,我们不得不使用:=句法,因为=是为比较保留的)
MySQL支持大量的列类型,它可以被分为3类:数字类型、日期和时间类型以及字符串(字符)类型。本节首先给出可用类型的一个概述,并且总结每个列类型的存储需求,然后提供每个类中的类型性质的更详细的描述。概述有意简化,更详细的说明应该考虑到有关特定列类型的附加信息,例如你能为其指定值的允许格式。
由MySQL支持的列类型列在下面。下列代码字母用于描述中:
指出最大的显示尺寸。最大的合法的显示尺寸是 255 。
适用于浮点类型并且指出跟随在十进制小数点后的数码的数量。最大可能的值是30,但是应该不大于M-2。
方括号(“[”和“]”)指出可选的类型修饰符的部分。
注意,如果你指定一个了为ZEROFILL,MySQL将为该列自动地增加UNSIGNED属性。
TINYINT[(M)] [UNSIGNED] [ZEROFILL]
一个很小的整数。有符号的范围是-128到127,无符号的范围是0到255。
SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
一个小整数。有符号的范围是-32768到32767,无符号的范围是0到65535。
MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
一个中等大小整数。有符号的范围是-8388608到8388607,无符号的范围是0到。
INT[(M)] [UNSIGNED] [ZEROFILL]
一个正常大小整数。有符号的范围是-到,无符号的范围是0到。
INTEGER[(M)] [UNSIGNED] [ZEROFILL]
这是INT的一个同义词。
BIGINT[(M)] [UNSIGNED] [ZEROFILL]
一个大整数。有符号的范围是-4775808到4775807,无符号的范围是0到。注意,所有算术运算用有符号的BIGINT或DOUBLE值完成,因此你不应该使用大于4775807(63位)的有符号大整数,除了位函数!注意,当两个参数是INTEGER值时,-、+和*将使用BIGINT运算!这意味着如果你乘2个大整数(或来自于返回整数的函数),如果结果大于4775807,你可以得到意外的结果。一个浮点数字,不能是无符号的,对一个单精度浮点数,其精度可以是&=24,对一个双精度浮点数,是在25
和53之间,这些类型如FLOAT和DOUBLE类型马上在下面描述。FLOAT(X)有对应的FLOAT和DOUBLE相同的范围,但是显示尺寸和小数位数是未定义的。在MySQL3.23中,这是一个真正的浮点值。在更早的MySQL版本中,FLOAT(precision)总是有2位小数。该句法为了ODBC兼容性而提供。
FLOAT[(M,D)] [ZEROFILL]
一个小(单精密)浮点数字。不能无符号。允许的值是-3.E+38到-1.E-38,0
和1.E-38到3.E+38。M是显示宽度而D是小数的位数。没有参数的FLOAT或有&24
的一个参数表示一个单精密浮点数字。
DOUBLE[(M,D)] [ZEROFILL]
一个正常大小(双精密)浮点数字。不能无符号。允许的值是-1.到-2.、
0和2.到1.。M是显示宽度而D是小数位数。没有一个参数的DOUBLE或FLOAT(X)(25
& = X & = 53)代表一个双精密浮点数字。
DOUBLE PRECISION[(M,D)] [ZEROFILL]
REAL[(M,D)] [ZEROFILL]
这些是DOUBLE同义词。
DECIMAL[(M[,D])] [ZEROFILL]
一个未压缩(unpack)的浮点数字。不能无符号。行为如同一个CHAR列:“未压缩”意味着数字作为一个字符串被存储,值的每一位使用一个字符。小数点,并且对于负数,“-”符号不在M中计算。如果D是0,值将没有小数点或小数部分。DECIMAL值的最大范围与DOUBLE相同,但是对一个给定的DECIMAL列,实际的范围可以通过M和D的选择被限制。如果D被省略,它被设置为0。如果M被省掉,它被设置为10。注意,在MySQL3.22里,M参数包括符号和小数点。
NUMERIC(M,D) [ZEROFILL]
这是DECIMAL的一个同义词。
一个日期。支持的范围是''到''。MySQL以'YYYY-MM-DD'格式来显示DATE值,但是允许你使用字符串或数字把值赋给DATE列。
一个日期和时间组合。支持的范围是' 00:00:00'到'
23:59:59'。MySQL以'YYYY-MM-DD HH:MM:SS'格式来显示DATETIME值,但是允许你使用字符串或数字把值赋给DATETIME的列。
TIMESTAMP[(M)]
一个时间戳记。范围是' 00:00:00'到2037年的某时。MySQL以YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD或YYMMDD格式来显示TIMESTAMP值,取决于是否M是14(或省略)、12、8或6,但是允许你使用字符串或数字把值赋给TIMESTAMP列。一个TIMESTAMP列对于记录一个INSERT或UPDATE操作的日期和时间是有用的,因为如果你不自己给它赋值,它自动地被设置为最近操作的日期和时间。你以可以通过赋给它一个NULL值设置它为当前的日期和时间。见。
一个时间。范围是'-838:59:59'到'838:59:59'。MySQL以'HH:MM:SS'格式来显示TIME值,但是允许你使用字符串或数字把值赋给TIME列。
YEAR[(2|4)]
一个2或4位数字格式的年(缺省是4位)。允许的值是1901到2155,和0000(4位年格式),如果你使用2位,(
70-69)。MySQL以YYYY格式来显示YEAR值,但是允许你把使用字符串或数字值赋给YEAR列。(YEAR类型在MySQL3.22中是新类型。)
CHAR(M) [BINARY]
一个定长字符串,当存储时,总是是用空格填满右边到指定的长度。M的范围是1
~ 255个字符。当值被检索时,空格尾部被删除。CHAR值根据缺省字符集以大小写不区分的方式排序和比较,除非给出BINARY关键词。NATIONAL
CHAR(短形式NCHAR)是ANSI SQL的方式来定义CHAR列应该使用缺省字符集。这是MySQL的缺省。CHAR是CHARACTER的一个缩写。
[NATIONAL] VARCHAR(M) [BINARY]
一个变长字符串。注意:当值被存储时,尾部的空格被删除(这不同于ANSI
SQL规范)。M的范围是1 ~ 255个字符。 VARCHAR值根据缺省字符集以大小写不区分的方式排序和比较,除非给出BINARY关键词值。见。 VARCHAR是CHARACTER
VARYING一个缩写。
一个BLOB或TEXT列,最大长度为255(2^8-1)个字符。见。
一个BLOB或TEXT列,最大长度为-1)个字符。见。
MEDIUMBLOB
MEDIUMTEXT
一个BLOB或TEXT列,最大长度为^24-1)个字符。见。
一个BLOB或TEXT列,最大长度为(2^32-1)个字符。见
ENUM('value1','value2',...)
枚举。一个仅有一个值的字符串对象,这个值式选自与值列表'value1'、'value2',
...,或NULL。一个ENUM最多能有65535不同的值。
SET('value1','value2',...)
一个集合。能有零个或多个值的一个字符串对象,其中每一个必须从值列表'value1',
'value2', ...选出。一个SET最多能有64个成员。
对于每个由MySQL支持的列类型的存储需求在下面按类列出。
7.3.2 数字类型
需要的存储量
4 如果 X & = 24 或 8 如果 25 & = X & = 53
DOUBLE PRECISION
DECIMAL(M,D)
M字节(D+2 , 如果M & D)
NUMERIC(M,D)
M字节(D+2 , 如果M & D)
7.3.3 日期和时间类型
需要的存储量
7.3.4 串类型
需要的存储量
M字节,1 &= M &= 255
VARCHAR(M)
L+1 字节, 在此L &= M和1 &= M &= 255
TINYBLOB, TINYTEXT
L+1 字节, 在此L& 2 ^ 8
BLOB, TEXT
L+2 字节, 在此L& 2 ^ 16
MEDIUMBLOB, MEDIUMTEXT
L+3 字节, 在此L& 2 ^ 24
LONGBLOB, LONGTEXT
L+4 字节, 在此L& 2 ^ 32
ENUM('value1','value2',...)
1 或 2 个字节, 取决于枚举值的数目(最大值65535)
SET('value1','value2',...)
1,2,3,4或8个字节, 取决于集合成员的数量(最多64个成员)
VARCHAR和BLOB和TEXT类型是变长类型,对于其存储需求取决于列值的实际长度(在前面的表格中用L表示),而不是取决于类型的最大可能尺寸。例如,一个VARCHAR(10)列能保存最大长度为10个字符的一个字符串,实际的存储需要是字符串的长度(L),加上1个字节以记录字符串的长度。对于字符串'abcd',L是4而存储要求是5个字节。
BLOB和TEXT类型需要1,2,3或4个字节来记录列值的长度,这取决于类型的最大可能长度。
如果一个表包括任何变长的列类型,记录格式将也是变长的。注意,当一个表被创建时,MySQL可能在某些条件下将一个列从一个变长类型改变为一个定长类型或相反。见。
一个ENUM对象的大小由不同枚举值的数量决定。1字节被用于枚举,最大到255个可能的值;2个字节用于枚举,最大到65535
一个SET对象的大小由不同的集合成员的数量决定。如果集合大小是N,对象占据(N+7)/8个字节,四舍五入为1,2,3,4或8
个字节。一个SET最多能有64个成员。
MySQL支持所有的ANSI/ISO SQL92的数字类型。这些类型包括准确数字的数据类型(NUMERIC,
DECIMAL, INTEGER,和SMALLINT),也包括近似数字的数据类型(FLOAT,
REAL,和DOUBLE PRECISION)。关键词INT是INTEGER的一个同义词,而关键词DEC是DECIMAL一个同义词。
NUMERIC和DECIMAL类型被MySQL实现为同样的类型,这在SQL92标准允许。他们被用于保存值,该值的准确精度是极其重要的值,例如与金钱有关的数据。当声明一个类是这些类型之一时,精度和规模的能被(并且通常是)指定;例如:
salary DECIMAL(9,2)
在这个例子中,9(precision)代表将被用于存储值的总的小数位数,而2(scale)代表将被用于存储小数点后的位数。因此,在这种情况下,能被存储在salary列中的值的范围是从-到。在ANSI/ISO
SQL92中,句法DECIMAL(p)等价于DECIMAL(p,0)。同样,句法DECIMAL等价于DECIMAL(p,0),这里实现被允许决定值p。MySQL当前不支持DECIMAL/NUMERIC数据类型的这些变种形式的任一种。这一般说来不是一个严重的问题,因为这些类型的主要益处得自于明显地控制精度和规模的能力。
DECIMAL和NUMERIC值作为字符串存储,而不是作为二进制浮点数,以便保存那些值的小数精度。一个字符用于值的每一位、小数点(如果scale&0)和“-”符号(对于负值)。如果scale是0,DECIMAL和NUMERIC值不包含小数点或小数部分。
DECIMAL和NUMERIC值得最大的范围与DOUBLE一样,但是对于一个给定的DECIMAL或NUMERIC列,实际的范围可由制由给定列的precision或scale限制。当这样的列赋给了小数点后面的位超过指定scale所允许的位的值,该值根据scale四舍五入。当一个DECIMAL或NUMERIC列被赋给了其大小超过指定(或缺省的)precision和scale隐含的范围的值,MySQL存储表示那个范围的相应的端点值。
作为对ANSI/ISO SQL92标准的扩展,MySQL也支持上表所列的整型类型TINYINT、MEDIUMINT和BIGINT。另一个扩展是MySQL支持可选地指定一个整型值显示的宽度,用括号跟在基本关键词之后(例如,INT(4))。这个可选的宽度指定被用于其宽度小于列指定宽度的值得左填补显示,但是不限制能在列中被存储的值的范围,也不限制值将被显示的位数,其宽度超过列指定的宽度。当与可选的扩展属性ZEROFILL一起使用时,缺省的空格填补用零代替。例如,对于声明为INT(5)
ZEROFILL的列,一个为4的值作为00004被检索。注意,如果你在一个整型列存储超过显示宽度的更大值,当MySQL对于某些复杂的联结(join)生成临时表时,你可能会遇到问题,因为在这些情况下,MySQL相信数据确实适合原来的列宽度。
所有的整型类型可以有一个可选(非标准的)属性UNSIGNED。当你想要在列中仅允许正数并且你需要一个稍大一点的列范围,可以使用无符号值。
FLOAT类型被用来标示近似数字的数据类型。ANSI/ISO SQL92标准允许一个可选的精度说明(但不是指数的范围),跟在关键词FLOAT后面的括号内位数。MySQL实现也支持这个可选的精度说明。当关键词FLOAT被用于一个列类型而没有精度说明时,MySQL使用4个字节存储值。一个变种的句法也被支持,在FLOAT关键词后面的括号给出2个数字。用这个选项,第一个数字继续表示在字节计算的值存储需求,而第二个数字指定要被存储的和显示跟随小数点后的位数(就象DECIMAL和NUMERIC)。当MySQL要求为这样一个列,一个小数点后的小数位超过列指定的值,存储值时,该值被四舍五入,去掉额外的位。
REAL和DOUBLE PRECISION类型不接受精度说明。作为对
ANSI/ISO SQL92 标准的扩展,MySQL识别出DOUBLE作为DOUBLE
PRECISION类型的一个同义词。与REAL精度比用于DOUBLE
PRECISION的更小的标准要求相反,MySQL实现了两种,作为8字节双精度浮点值(当运行不是“Ansi模式”时)。为了最大的移植性,近似数字的数据值的存储所需代码应该使用没有精度或小数位数说明的FLOAT或DOUBLE
PRECISION。
当要求在数字的列存储超出该列类型允许的范围的值时,MySQL剪切该值到范围内的正确端点值并且存储剪切后的结果值。
例如,一个INT列的范围是-到。如果你试图插入-到一个INT列中,值被剪切到范围的低部端点,并存储-。同样,如果你试图插入,被存储。
如果INT列是UNSIGNED,列的范围的大小是相同的,但是它的端点移到了0和。如果你试图存储-和,在列被存储的值变为0和。
对于ALTER TABLE、LOAD DATA INFILE、UPDATE和多行INSERT语句,由于剪切所发生的变换作为“警告”被报告。
日期和时间类型是DATETIME、DATE、TIMESTAMP、TIME和YEAR。这些的每一个都有合法值的一个范围,而“零”当你指定确实不合法的值时被使用。注意,MySQL允许你存储某个“不严格地”合法的日期值,例如,原因我们认为它是应用程序的责任来处理日期检查,而不是SQL服务器。为了使日期检查更“快”,MySQL仅检查月份在0-12的范围,天在0-31的范围。上述范围这样被定义是因为MySQL允许你在一个DATE或DATETIME列中存储日期,这里的天或月是零。这对存储你不知道准确的日期的一个生日的应用程序来说是极其有用的,在这种情况下,你简单地存储日期象或。(当然你不能期望从函数如DATE_SUB()或DATE_ADD()得到类似以这些日期的正确值)。
当用日期和时间工作时,这里是的一些要记住的一般考虑:
MySQL对一个给定的日期或时间类型以标准的格式检索,但是它试图为你提供的值解释成许多格式(例如,当你指定一个值被赋给或与比较一个日期或时间类型时),但是只支持有在下列小节描述的格式。期望你提供合法的值,并且如果你以其他格式使用这些值,可能造成无法预料的结果。
尽管MySQL试图以多种格式解释值,但它总是期望日期值的年份部分在最左面,日期必须以年-月-日的顺序给出(例如,'98-09-04'),而不是以其他地方常用的月-日-年或日-月-年的次序(例如,'09-04-98'、'04-09-98')。
如果一个值在数字的上下文环境中被使用,MySQL自动变换一个日期或时间类型值到一个数字,反过来也如此。
当MySQL遇到一个日期或时间类型的值超出范围或对给类型不合法(见本节的开始)时,它将该类型的值变换到“零”值。(例外的是超出范围的TIME值被剪切为适当的TIME范围端点值。)下表显示对每种类型的“零”值的格式:
' 00:00:00'
00(长度取决于显示尺寸)
'00:00:00'
“零”值是特殊的,但是你能使用在表中显示的值来明显地存储或引用他们。你也可以使用值'0'或0做到,
这更容易写。
在MyODBC 2.50.12和以上版本中,由MyODBC使用的“零”日期或时间值被自动变换到NULL,因为ODBC不能处理这样的值。
MySQL本身Y2K安全的(见),但是呈交给MySQL的输入值可能不是。一个包含2位年份值的任何输入是由二义性的,因为世纪是未知的。这样的值必须被解释成4位形式,因为MySQL内部使用4位存储年份。
对于DATETIME, DATE, TIMESTAMP和YEAR类型,MySQL使用下列规则的解释二义性的年份值:
在范围00-69的年值被变换到。
在范围70-99的年值被变换到。
记得这些规则仅仅提供对于你数据的含义的合理猜测。如果MySQL使用的启发规则不产生正确的值,你应该提供无二义的包含4位年值的输入。
DATETIME, DATE和TIMESTAMP类型是相关的。本节描述他们的特征,他们是如何类似的而又不同的。
DATETIME类型用在你需要同时包含日期和时间信息的值时。MySQL检索并且以'YYYY-MM-DD
HH:MM:SS'格式显示DATETIME值,支持的范围是'
00:00:00'到' 23:59:59'。(“支持”意味着尽管更早的值可能工作,但不能保证他们可以。)
DATE类型用在你仅需要日期值时,没有时间部分。MySQL检索并且以'YYYY-MM-DD'格式显示DATE值,支持的范围是''到''。
TIMESTAMP列类型提供一种类型,你可以使用它自动地用当前的日期和时间标记INSERT或UPDATE的操作。如果你有多个TIMESTAMP列,只有第一个自动更新。
自动更新第一个TIMESTAMP列在下列任何条件下发生:
列没有明确地在一个INSERT或LOAD DATA INFILE语句中指定。
列没有明确地在一个UPDATE语句中指定且一些另外的列改变值。(注意一个UPDATE设置一个列为它已经有的值,这将不引起TIMESTAMP列被更新,因为如果你设置一个列为它当前的值,MySQL为了效率而忽略更改。)
你明确地设定TIMESTAMP列为NULL.
除第一个以外的TIMESTAMP列也可以设置到当前的日期和时间,只要将列设为NULL,或NOW()。
通过明确地设置希望的值,你可以设置任何TIMESTAMP列为不同于当前日期和时间的值,即使对第一个TIMESTAMP列也是这样。例如,如果,当你创建一个行时,你想要一个TIMESTAMP被设置到当前的日期和时间,但在以后无论何时行被更新时都不改变,你可以使用这个属性:
让MySQL在行被创建时设置列,这将初始化它为当前的日期和时间。
当你执行随后的对该行中其他列的更改时,明确设定TIMESTAMP列为它的当前值。
另一方面,你可能发现,当行被创建并且远离随后的更改时,很容易用一个你用NOW()初始化的DATETIME列。
TIMESTAMP值可以从1970的某时的开始一直到2037年,精度为一秒,其值作为数字显示。
在MySQL检索并且显示TIMESTAMP值取决于显示尺寸的格式如下表。“完整”TIMESTAMP格式是14位,但是TIMESTAMP列可以用更短的显示尺寸创造:
TIMESTAMP(14)
YYYYMMDDHHMMSS
TIMESTAMP(12)
YYMMDDHHMMSS
TIMESTAMP(10)
YYMMDDHHMM
TIMESTAMP(8)
TIMESTAMP(6)
TIMESTAMP(4)
TIMESTAMP(2)
所有的TIMESTAMP列都有同样的存储大小,不考虑显示尺寸。最常见的显示尺寸是6、8、12、和14。你可以在表创建时间指定一个任意的显示尺寸,但是值0或比14大被强制到14。在从1~13范围的奇数值尺寸被强制为下一个更大的偶数。
使用一个常用的格式集的任何一个,你可以指定DATETIME、DATE和TIMESTAMP值:
'YYYY-MM-DD HH:MM:SS'或'YY-MM-DD HH:MM:SS'格式的一个字符串。允许一种“宽松”的语法--任何标点可用作在日期部分和时间部分之间的分隔符。例如,'98-12-31
11:30:45'、'98.12.31 11+30+45'、'98/12/31 11*30*45'和'98@12@31
11^30^45'是等价的。
'YYYY-MM-DD'或'YY-MM-DD'格式的一个字符串。允许一种“宽松”的语法。例如,'98-12-31',
'98.12.31', '98/12/31'和'98@12@31'是等价的。
'YYYYMMDDHHMMSS'或'YYMMDDHHMMSS'格式的没有任何分隔符的一个字符串,例如,'28'和''被解释为'
09:15:28',但是''是不合法的(它有毫无意义的分钟部分)且变成'
00:00:00'。
'YYYYMMDD'或'YYMMDD'格式的没有任何分隔符的一个字符串,如果字符串认为是一个日期。例如,''和'970523'被解释作为'',但是'971332'是不合法的(
它有无意义的月和天部分)且变成''。
YYYYMMDDHHMMSS或YYMMDDHHMMSS格式的一个数字,如果数字认为是一个日期。例如,00和被解释作为'
13:28:00'。
YYYYMMDD或YYMMDD格式的一个数字,如果数字认为是一个日期。例如,和830905被解释作为''。
一个返回值可以在一个DATETIME, DATE或TIMESTAMP上下文环境中接受的函数,例如NOW()或CURRENT_DATE。
不合法DATETIME, DATE或TIMESTAMP值被变换到适当类型的“零”值('
00:00:00', ''或00)。
对于包括的日期部分分隔符的指定为字符串的值,不必要为小于10的月或天的值指定2位数字,''与''是一样的。同样,
对于包括的时间部分分隔符的指定为字符串的值,不必为小于10的小时、月或秒指定2位数字,'
1:2:3'与' 01:02:03'是一样的。
指定为数字应该是6、8、12或14位长。如果数字是8或14位长,它被假定以YYYYMMDD或YYYYMMDDHHMMSS格式并且年份由头4位数字给出。如果数字是6或12位长,它被假定是以YYMMDD或YYMMDDHHMMSS格式且年份由头2位数字给出。不是这些长度之一的数字通过填补前头的零到最接近的长度来解释。
指定为无分隔符的字符串用它们给定的长度来解释。如果字符串长度是8或14个字符,年份被假定头4个字符给出,否则年份被假定由头2个字符给出。对于字符串中呈现的多个部分,字符串从左到右边被解释,以找出年、月、日、小时、分钟和秒值,这意味着,你不应该使用少于
6 个字符的字符串。例如,如果你指定'9903',认为将代表1999年3月,你会发现MySQL把一个“零”日期插入到你的表中,这是因为年份和月份值99和03,但是日期部分丢失(零),因此该值不是一个合法的日期。
TIMESTAMP列使用被指定的值的完整精度的存储合法的值,不考虑显示大小。这有几个含意:
总是指定年,月,和日,即使你的列类型是TIMESTAMP(4)或TIMESTAMP(2)。否则,值将不是一个合法的日期并且0将被存储。
如果你使用ALTER TABLE拓宽一个狭窄的TIMESTAMP列,以前被“隐蔽”的信息将被显示。
同样,缩小一个TIMESTAMP列不会导致信息失去,除了感觉上值在显示时,较少的信息被显示出。
尽管TIMESTAMP值被存储为完整精度,直接操作存储值的唯一函数是UNIX_TIMESTAMP(),其他函数操作在格式化了的检索的值上,这意味着你不能使用函数例如HOUR()或SECOND(),除非TIMESTAMP值的相关部分被包含在格式化的值中。例如,一个TIMESTAMP列的HH部分部被显示,除非显示大小至少是10,因此在更短的TIMESTAMP值上试试使用HOUR()产生一个无意义的结果。
在某种程度上,你可以把一种日期类型的值赋给一个不同的日期类型的对象。然而,这可能值有一些改变或信息的损失:
如果你将一个DATE值赋给一个DATETIME或TIMESTAMP对象,结果值的时间部分被设置为'00:00:00',因为DATE值不包含时间信息。
如果你将一个DATETIME或TIMESTAMP值赋给一个DATE对象,结果值的时间部分被删除,因为DATE类型不存储时间信息。
记住,尽管DATETIME, DATE和TIMESTAMP值全都可以用同样的格式集来指定,但所有类型不都有同样的值范围。例如,TIMESTAMP值不能比1970早或比2037网晚,这意味着,一个日期例如'',当作为一个DATETIME或DATE值合法时,它不是一个正确TIMESTAMP值,并且如果赋值给这样一个对象,它将被变换到0。
当指定日期值时,当心某些缺陷:
允许作为字符串指定值的宽松格式能被欺骗。例如,值例如'10:11:12'可能看起来像时间值,因为“:”分隔符,但是如果在一个日期中使用,上下文将作为年份被解释成''。值'10:45:15'将被变换到'',因为'45'不是一个合法的月份。
以2位数字指定的年值是模糊的,因为世纪是未知的。MySQL使用下列规则解释2位年值:
在00-69范围的年值被变换到。
在范70-99围的年值被变换到。
MySQL检索并以'HH:MM:SS'格式显示TIME值(或对大小时值,'HHH:MM:SS'格式)。TIME值的范围可以从'-838:59:59'到'838:59:59'。小时部分可能很大的的原因是TIME类型不仅可以被使用在表示一天的时间(它必须是不到24个小时),而且用在表示在2个事件之间经过的时间或时间间隔(它可以是比24个小时大些,或甚至是负值)。
你能用多中格式指定TIME值:
作为'HH:MM:SS'格式的一个字符串。“宽松”的语法被允许--任何标点符号可用作时间部分的分隔符,例如,'10:11:12'和'10.11.12'是等价的。
作为没有分隔符的'HHMMSS'格式的一个字符串,如果它作为一个时间解释。例如,'101112'被理解为'10:11:12',但是'109712'是不合法的(它有无意义的分钟部分)并变成'00:00:00'。
作为HHMMSS格式的一个数字,如果它能解释为一个时间。例如,101112被理解为'10:11:12'。
返回值可在一个TIME上下文接受的函数,例如CURRENT_TIME。
对于作为包括一个时间分隔符的字符串被指定的TIME值,不必为小于10的小时、分钟或秒值指定2位数字,'8:3:2'与'08:03:02'是一样的。
将“短的”TIME值赋值给一个TIME行列是要格外小心。MySQL使用最右位代表秒的假设来解释值。(MySQL将TIME值解释为经过的时间,而非作为一天的时间
)例如,你可能想到'11:12'、'1112'和1112意味着'11:12:00'(11点12分),但是MySQL解释他们为'00:11:12'(11分12秒)。同样,'12'和12被解释为'00:00:12'。
但是超出TIME范围之外的值是样合法的,它被剪切到范围适当的端点值。例如,'-850:00:00'和'850:00:00'被变换到'-838:59:59'和'838:59:59'。
不合法的TIME值被变换到'00:00:00'。注意,既然'00:00:00'本身是一个合法的TIME值,没有其他方法区分表中存储的一个'00:00:00'值,原来的值是否被指定为'00:00:00'或它是否是不合法的。
YEAR类型是一个 1 字节类型用于表示年份。
MySQL检索并且以YYYY格式显示YEAR值,其范围是1901到2155。
你能用多种格式指定YEAR值:
作为在'1901'到'2155'范围的一个4位字符串。
作为在1901到2155范围的一个4位数字。
作为在'00'到'99'范围的一个2位字符串.在'00'到'69'和'70'到'99'范围的值被变换到在2000到2069范围和1970到1999的YEAR值。
作为在1到99范围的一个2位数字。在范围1到69和70到99的值被变换到在范围2001到2069和1970到1999的YEAR的值。注意对于2位数字的范围略微不同于2位数字字符串的范围,因为你不能直接指定零作为一个数字并且把它解释为2000。你必须作为一个字符串'0'或'00'指定它,它将被解释为0000。
其返回值可在一个YEAR上下文环境中接受的函数,例如NOW()。
不合法YEAR值被变换到0000。
字符串类型是CHAR、VARCHAR、BLOB、TEXT、ENUM和SET。
CHAR和VARCHAR类型是类似的,但是在他们被存储和检索的方式不同。
一个CHAR列的长度被修正为在你创造表时你所声明的长度。长度可以是1和255之间的任何值。(在MySQL
3.23中,CHAR长度可以是0~255。) 当CHAR值被存储时,他们被用空格在右边填补到指定的长度。当CHAR值被检索时,拖后的空格被删去。
在VARCHAR列中的值是变长字符串。你可以声明一个VARCHAR列是在1和255之间的任何长度,就像对CHAR列。然而,与CHAR相反,VARCHAR值只存储所需的字符,外加一个字节记录长度,值不被填补;相反,当值被存储时,拖后的空格被删去。(这个空格删除不同于ANSI
SQL规范。)
如果你把一个超过列最大长度的值赋给一个CHAR或VARCHAR列,值被截断以适合它。
下表显示了两种类型的列的不同,通过演示存储变长字符串值到CHAR(4)和VARCHAR(4)列:
VARCHAR(4)
'abcdefgh'
从CHAR(4)和VARCHAR(4)列检索的值在每种情况下都是一样的,因为拖后的空格从检索的CHAR列上被删除。
在CHAR和VARCHAR列中存储和比较值是以大小写不区分的方式进行的,除非当桌子被创建时,BINARY属性被指定。BINARY属性意味着该列的值根据MySQL服务器正在运行的机器的ASCII顺序以大小写区分的方式存储和比较。
BINARY属性是“粘性”的。这意味着,如果标记了BINARY的列用于一个表达式中,整个的表达式作为一个BINARY值被比较。
MySQL在表创建时可以隐含地改变一个CHAR或VARCHAR列的类型。见。
一个BLOB是一个能保存可变数量的数据的二进制的大对象。4个BLOB类型TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB仅仅在他们能保存值的最大长度方面有所不同。见。
4个TEXT类型TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT对应于4个BLOB类型,并且有同样的最大长度和存储需求。在BLOB和TEXT类型之间的唯一差别是对BLOB值的排序和比较以大小写敏感方式执行,而对TEXT值是大小写不敏感的。换句话说,一个TEXT是一个大小写不敏感的BLOB。
如果你把一个超过列类型最大长度的值赋给一个BLOB或TEXT列,值被截断以适合它。
在大多数方面,你可以认为一个TEXT行列是你所希望大的一个VARCHAR列。同样,你可以认为一个BLOB列是一个VARCHAR
BINARY列。差别是:
用MySQL版本3.23.2和更新,你能在BLOB和TEXT列上索引。更旧的MySQL版本不支持这个。
当值被存储时,对BLOB和TEXT列没有拖后空格的删除,因为对VARCHAR列有删除。
BLOB和TEXT列不能有DEFAULT值。
MyODBC定义BLOB为LONGVARBINARY,TEXT值为LONGVARCHAR。
因为BLOB和TEXT值可以是非常长的,当使用他们时,你可能遇到一些限制:
如果你想要在一个BLOB或TEXT列上使用GROUP BY或ORDER
BY,你必须将列值变换成一个定长对象。这样做的标准方法是用SUBSTRING函数。例如:
mysql& select comment from tbl_name,substring(comment,20) as substr ORDER BY
如果你不这样做,在排序时,只有列的首max_sort_length个字节被使用,缺省的max_sort_length是1024;这个值能在启动mysqld服务器时使用-O选择改变。你可以在包含BLOB或TEXT值得一个表达式上分组(group),通过指定列的位置或使用一个别名:
mysql& select id,substring(blob_col,1,100) from tbl_name
GROUP BY 2;
mysql& select id,substring(blob_col,1,100) as b from tbl_name
一个BLOB或TEXT对象的最大尺寸由其类型决定,但是你能在客户与服务器之间是实际传输的最大值由可用的内存数量和通讯缓冲区的大小来决定。你能改变消息缓冲区大小,但是你必须在服务器和客户两端做。见。
注意,每个BLOB或TEXT值内部由一个独立分配的对象表示。这与所有的其他列类型相反,它们是在打开表时,按列被分配一次存储。
一个ENUM是一个字符对象,其值通常从一个在表创建时明确被列举的允许值的一张表中选择。
在下列的某个情形下,值也可以空字符串(&&)或NULL:
如果你把一个无效值插入到一个ENUM(即,一个不在允许的值列表中的字符串),空字符串作为一个特殊错误的值被插入。
如果一个ENUM被声明为NULL,NULL也是列的合法值,并且缺省值是NULL。如果一个ENUM被声明为NOT
NULL,缺省值是允许值的列表的第一成员。
每枚举值有一个编号:
在列说明中来自允许成员值列表值用从1开始编号。
空字符串错误值的编号值是0。这意味着,你能使用下列SELECT语句找出被赋给无效ENUM值的行:
mysql& SELECT * FROM tbl_name WHERE enum_col=0;
NULL值的编号是NULL。
例如,指定为ENUM(&one&, &two&, &three&)的列可以有显示在下面的值的任何一个。每个值的编号也被显示:
枚举可以有最大65535个成员。
当你把值赋给一个ENUM列时,字母的大小写是无关紧要的。然而,以后从列中检索的值大小写匹配在表创建时用来指定允许值的值的大小写。
如果你在一个数字的上下文环境中检索一个ENUM,列值的编号被返回。如果你存储一个数字到一个ENUM中,数字被当作一个标号,并且存储的值是该编号的枚举成员。
ENUM值根据列说明列举的枚举成员的次序被排序。(换句话说,ENUM值根据他们的编号数字被排序)
例如,对ENUM(&a&, &b&),&a&排在&b&前面,但是对ENUM(&b&,
&a&),&b&排在&a&前面。空字符串排序非空字符串之前,并且NULL排在所有其他枚举值之前。
如果你想要得到一个ENUM列的所有可能的值,你应该使用:SHOW
COLUMNS FROM table_name LIKE enum_column_name并且分析在第二列的ENUM定义。
一个SET是可以有零或多个值的一个字符串对象,其每一个必须从表创建造被指定了的允许值的一张列表中被选择。由多个集合成员组成的SET列通过由由逗号分隔(“,”)的成员被指定,其推论是该SET成员值不能包含逗号本身。
例如, 一个指定为SET(&one&, &two&) NOT NULL的列可以有这些值的任何一个:
一个SET能有最多64个不同的成员。
MySQL用数字值存储SET值,存储值的低阶位对应于第一个集合成员。如果你在数字上下文中检索一个SET值,检索的值把位设置位对应组成列值的集合成员。如果一个数字被存储进一个SET列,在数字的二进制表示中设置的位决定了在列中的集合成员。假定一个列被指定为SET(&a&,&b&,&c&,&d&),那么成员有下列位值:
十进制的值
二进制的值
如果你给该列赋值9,即二进制的1001,这样第一个和第四个SET值成员&a&和&d&被选择并且结果值是&a,d&。
对于包含超过一个SET成员的值,当你插入值时,无所谓以什么顺序列举值,也无所谓给定的值列举了多少次。当以后检索值时,在值中的每个成员将出现一次,根据他们在表创建时被指定的顺序列出成员。例如,如果列指定为SET(&a&,&b&,&c&,&d&),那么&a,d&、&d,a&和&d,a,a,d,d&在检索时将均作为&a,d&出现。
SET值以数字次序被排序。NULL指排在非NULL
SET值之前。
通常,你使用LIKE操作符或FIND_IN_SET()函数执行在一个SET上的一个SELECT:
mysql& SELECT * FROM tbl_name WHERE set_col LIKE '%value%';
mysql& SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)&0;
但是下列也会工作:
mysql& SELECT * FROM tbl_name WHERE set_col = 'val1,val2';
mysql& SELECT * FROM tbl_name WHERE set_col & 1;
这些语句的第一个语句寻找一个精确的匹配。第二个寻找包含第一个集合成员的值。
如果你想要得到一个SET列的所有可能的值,你应该使用:SHOW
COLUMNS FROM table_name LIKE set_column_name并且分析在第二列的SET定义。
为了最有效地使用存储空间,试着在所有的情况下使用最精确的类型。例如,如果一个整数列被用于在之间1和99999的值,
MEDIUMINT UNSIGNED是最好的类型。
货币值的精确表示是一个常见的问题。在MySQL,你应该使用DECIMAL类型,它作为一个字符串被存储,不会发生精确性的损失。如果精确性不是太重要,DOUBLE类型也是足够好的。
对高精度,你总是能变换到以一个BIGINT存储的定点类型。这允许你用整数做所有的计算,并且仅在必要时将结果转换回浮点值。见。
所有的MySQL列类型能被索引。在相关的列上的使用索引是改进SELECT操作性能的最好方法。
一个表最多可有16个索引。最大索引长度是256个字节,尽管这可以在编译MySQL时被改变。
对于CHAR和VARCHAR列,你可以索引列的前缀。这更快并且比索引整个列需要较少的磁盘空间。在CREATE
TABLE语句中索引列前缀的语法看起来像这样:
KEY index_name (col_name(length))
下面的例子为name列的头10个字符创建一个索引:
mysql& CREATE TABLE test (
name CHAR(200) NOT NULL,
KEY index_name (name(10)));
对于BLOB和TEXT列,你必须索引列的前缀,你不能索引列的全部。
MySQL能在多个列上创建索引。一个索引可以由最多15个列组成。(在CHAR和VARCHAR列上,你也可以使用列的前缀作为一个索引的部分)。
一个多重列索引可以认为是包含通过合并(concatenate)索引列值创建的值的一个排序数组。
当你为在一个WHERE子句索引的第一列指定已知的数量时,MySQL以这种方式使用多重列索引使得查询非常快速,即使你不为其他列指定值。
假定一张表使用下列说明创建:
mysql& CREATE TABLE test (
id INT NOT NULL,
last_name CHAR(30) NOT NULL,
first_name CHAR(30) NOT NULL,
PRIMARY KEY (id),
INDEX name (last_name,first_name));
那么索引name是一个在last_name和first_name上的索引,这个索引将被用于在last_name或last_name和first_name的一个已知范围内指定值的查询,因此,name索引将使用在下列查询中:
mysql& SELECT * FROM test WHERE last_name=&Widenius&;
mysql& SELECT * FROM test WHERE last_name=&Widenius&
AND first_name=&Michael&;
mysql& SELECT * FROM test WHERE last_name=&Widenius&
AND (first_name=&Michael& OR first_name=&Monty&);
mysql& SELECT * FROM test WHERE last_name=&Widenius&
AND first_name &=&M& AND first_name & &N&;
然而,name索引将不用在下列询问中:
mysql& SELECT * FROM test WHERE first_name=&Michael&;
mysql& SELECT * FROM test WHERE last_name=&Widenius&
OR first_name=&Michael&;
关于MySQL使用索引改进性能的方式的更多的信息,见。
为了跟容易地使用为其他供应商的SQL实现编写的代码,下表显示了MySQL映射的列类型。这些映射使得从其他数据库引擎移动表定义到MySQL更容易:
其他供应商类型
BINARY(NUM)
CHAR(NUM) BINARY
CHAR VARYING(NUM)
VARCHAR(NUM)
LONG VARBINARY
MEDIUMBLOB
LONG VARCHAR
MEDIUMTEXT
VARBINARY(NUM)
VARCHAR(NUM) BINARY
列类型映射发生在表创建时。如果你用其他供应商使用的类型创建表,那么发出一个DESCRIBE
tbl_name语句,MySQL使用等价的MySQL类型报告表结构。
在一个SQL语句中的select_expression或where_definition可由使用下面描述的函数的任何表达式组成。
包含NULL的一个表达式总是产生一个NULL值,否则除非表达式所包含的操作符和函数在文档中说明。
注意:在一个函数名和跟随它的括号之间不许没有空格。这帮助MySQL分析器区分函数调用和具有相同名字的对表或列的引用,尽管允许在参数周围有空格。
为了简洁,例子以缩写形式显示从mysql程序输出。因此:
mysql& select MOD(29,9);
1 rows in set (0.00 sec)
+-----------+
| mod(29,9) |
+-----------+
+-----------+
被显示为这样:
mysql& select MOD(29,9);
括号。使用它们来强制在一个表达式的计算顺序。
mysql& select 1+2*3;
mysql& select (1+2)*3;
一般的算术操作符是可用的。注意在-、+和*情况下,如果两个参数是整数,结果用BIGINT(64位)精度计算!
加法mysql& select 3+5;
减法mysql& select 3-5;
乘法mysql& select 3*5;
mysql& select .0;
mysql& select ;
最后一个表达式的结果是不正确的,因为整数乘积的结果超过用BIGINT计算的64位范围。
除法mysql& select 3/5;
被零除产生一个NULL结果:
mysql& select 102/(1-1);
一个除法用BIGINT算术计算,只要在它的结果被转换到一个整数的上下文中执行!
MySQL为位操作使用BIGINT(64位)算法,因此这些操作符有最大64位的一个范围。
位或mysql& select 29 | 15;
位与mysql& select 29 & 15;
左移位一个长(BIGINT)数字。 mysql& select 1 && 2
右移位一个长(BIGINT)数字。 mysql& select 4 && 2
颠倒所有的位。 mysql& select 5 & ~1
BIT_COUNT(N)
返回在参数N设定的位的数量。 mysql& select BIT_COUNT(29);
所有的逻辑函数返回1(TRUE)或0(FALSE)。
逻辑非。如果参数是0,返回1,否则返回0。例外:
NOT NULL返回NULL。 mysql& select NOT 1;
mysql& select NOT NULL;
mysql& select ! (1+1);
mysql& select ! 1+1;
最后的例子返回1,因为表达式作为(!1)+1计算。
逻辑或。如果任何一个参数不是0并且不NULL,返回1。
mysql& select 1 || 0;
mysql& select 0 || 0;
mysql& select 1 || NULL;
逻辑与。如果任何一个参数是0或NULL,返回0,否则返回1。
mysql& select 1 && NULL;
mysql& select 1 && 0;
比较操作得出值1(TRUE)、0(FALSE)或NULL等结果。这些函数工作运用在数字和字符串上。当需要时,字符串自动地被变换到数字且数字到字符串(如在Perl)。
MySQL使用下列规则执行比较:
如果一个或两个参数是NULL,比较的结果是NULL,除了&=&操作符。
如果在比较中操作的两个参数是字符串,他们作为字符串被比较。
如果两个参数是整数,他们作为整数被比较。
十六进制的值如果不与一个数字比较,则被当作二进制字符串。
如果参数之一是一个TIMESTAMP或DATETIME列而其他参数是一个常数,在比较执行前,常数被转换为一个时间标记。这样做是为了对ODBC更友好。
在所有其他的情况下,参数作为浮点(实数)数字被比较。
缺省地,字符串使用当前的字符集以大小写敏感的方式进行(缺省为ISO-8859-1
Latin1,它对英语运用得很出色)。
下面的例子演示了对于比较操作字符串到数字的转换:
mysql& SELECT 1 & '6x';
mysql& SELECT 7 & '6x';
mysql& SELECT 0 & 'x6';
mysql& SELECT 0 = 'x6';
等于mysql& select 1 = 0;
mysql& select '0' = 0;
mysql& select '0.0' = 0;
mysql& select '0.01' = 0;
mysql& select '.01' = 0.01;
不等于mysql& select '.01' && '0.01';
mysql& select .01 && '0.01';
mysql& select 'zapp' && 'zappp';
小于或等于
mysql& select 0.1 &= 2;
小于mysql& select 2 &= 2;
大于或等于mysql& select 2 &= 2;
大于mysql& select 2 & 2;
安全等于Nullmysql& select 1 &=& 1, NULL &=& NULL, 1 &=& NULL;
IS NOT NULL
测试值是否是或不是NULL mysql& select 1 IS NULL, 0 IS NULL, NULL IS NULL:
mysql& select 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
expr BETWEEN min AND max
如果expr对大于或等于min且expr是小于或等于max,BETWEEN返回1,否则它返回0。如果所有的参数类型是一样得,这等价于表达式(min
&= expr AND expr &= max)。第一个参数(expr)决定比较如何被执行。如果expr是一个大小写不敏感的字符串表达式,进行一个大小写不敏感的字符串比较。如果expr是一个大小写敏感的字符串表达式,进行一个大小写敏感的字符串比较。如果expr是一个整数表达式,进行整数比较。否则,进行一个浮点(实数)比较。
mysql& select 1 BETWEEN 2 AND 3;
mysql& select 'b' BETWEEN 'a' AND 'c';
mysql& select 2 BETWEEN 2 AND '3';
mysql& select 2 BETWEEN 2 AND 'x-3';
expr IN (value,...)
如果expr是在IN表中的任何值,返回1,否则返回0。如果所有的值是常数,那么所有的值根据expr类型被计算和排序,然后项目的搜索是用二进制的搜索完成。这意味着如果IN值表全部由常数组成,IN是很快的。如果expr是一个大小写敏感的字符串表达式,字符串比较以大小写敏感方式执行。
mysql& select 2 IN (0,3,5,'wefwf');
mysql& select 'wefwf' IN (0,3,5,'wefwf');
expr NOT IN (value,...)
与NOT (expr IN (value,...))相同。
ISNULL(expr)
如果expr是NULL,ISNULL()返回1,否则它返回0。
mysql& select ISNULL(1+1);
mysql& select ISNULL(1/0);
注意,使用=的NULL的值比较总为假!
COALESCE(list)
回来list中第一个非NULL的单元。 mysql& select COALESCE(NULL,1);
mysql& select COALESCE(NULL,NULL,NULL);
INTERVAL(N,N1,N2,N3,...)
如果N& N1,返回0,如果N&
N2,返回1等等。所有的参数被当作整数。为了函数能正确地工作,它要求N1&N2&N3&
...&Nn。这是因为使用二进制搜索(很快)。 mysql& select INTERVAL(23, 1, 15, 17, 30, 44, 200);
mysql& select INTERVAL(10, 1, 10, 100, 1000);
mysql& select INTERVAL(22, 23, 30, 44, 200);
通常,如果在字符串比较中的任何表达式是区分大小写的,比较以大小写敏感的方式执行。
expr LIKE pat [ESCAPE 'escape-char']
使用SQL的简单的正规表达式比较的模式匹配。返回1(TRUE)或0(FALSE)。用LIKE,你可以在模式中使用下列2个通配符字符:
匹配任何数目的字符,甚至零个字符
精确匹配一个字符
mysql& select 'David!' LIKE 'David_';
mysql& select 'David!' LIKE '%D%v%';
为了测试一个通配符的文字实例,用转义字符的加在字符前面。如果你不指定ESCAPE字符,假定为“\”:
匹配一%字符
匹配一_字符
mysql& select 'David!' LIKE 'David\_';
mysql& select 'David_' LIKE 'David\_';
为了指定一个不同的转义字符,使用ESCAPE子句:
mysql& select 'David_' LIKE 'David|_' ESCAPE '|';
LIKE允许用在数字的表达式上!(这是MySQL对ANSI
SQL LIKE的一个扩充。)
mysql& select 10 LIKE '1%';
注意:因为MySQL在字符串中使用C转义语法(例如,“\n”),你必须在你的LIKE字符串中重复任何“\”。例如,为了查找“\n”,指定它为“
\\n”,为了查找“\”,指定它为“\\\\”(反斜线被分析器剥去一次,另一次是在模式匹配完成时,留下一条单独的反斜线被匹配)。
expr NOT LIKE pat [ESCAPE 'escape-char']
与NOT (expr LIKE pat [ESCAPE 'escape-char'])相同。
expr REGEXP pat
expr RLIKE pat
执行一个字符串表达式expr对一个模式pat的模式匹配。模式可以是一个扩充的正则表达式。见.如果expr匹配pat,返回1,否则返回0。RLIKE是REGEXP的一个同义词,提供了与mSQL的兼容性。注意:因为MySQL在字符串中使用C转义语法(例如,“\n”),
你必须在你的REGEXP字符串重复任何“\”。在MySQL3.23.4中,REGEXP对于正常的(不是二进制)字符串是忽略大小写。
mysql& select 'Monty!' REGEXP 'm%y%%';
mysql& select 'Monty!' REGEXP '.*';
mysql& select 'new*\n*line' REGEXP 'new\\*.\\*line';
mysql& select &a& REGEXP &A&, &a& REGEXP BINARY &A&;
当决定一个字符的类型时,REGEXP和RLIKE使用当前的字符集(缺省为ISO-8859-1
expr NOT REGEXP pat
expr NOT RLIKE pat
与NOT (expr REGEXP pat)相同。
STRCMP(expr1,expr2)
如果字符串相同,STRCMP()回来0,如果第一参数根据当前的排序次序小于第二个,返回-1,否则返回1。
mysql& select STRCMP('text', 'text2');
mysql& select STRCMP('text2', 'text');
mysql& select STRCMP('text', 'text');
BINARY操作符强制跟随它后面的字符串为一个二进制字符串。即使列没被定义为BINARY或BLOB,这是一个强制列比较区分大小写的简易方法。
mysql& select &a& = &A&;
mysql& select BINARY &a& = &A&;
BINARY在MySQL 3.23.0中被引入。
IFNULL(expr1,expr2)
如果expr1不是NULL,IFNULL()返回expr1,否则它返回expr2。IFNULL()返回一个数字或字符串值,取决于它被使用的上下文环境。
mysql& select IFNULL(1,0);
mysql& select IFNULL(0,10);
mysql& select IFNULL(1/0,10);
mysql& select IFNULL(1/0,'yes');
IF(expr1,expr2,expr3)
如果expr1是TRUE(expr1&&0且expr1&&NULL),那么IF()返回expr2,否则它返回expr3。IF()返回一个数字或字符串值,取决于它被使用的上下文。
mysql& select IF(1&2,2,3);
mysql& select IF(1&2,'yes','no');
mysql& select IF(strcmp('test','test1'),'yes','no');
expr1作为整数值被计算,它意味着如果你正在测试浮点或字符串值,你应该使用一个比较操作来做。
mysql& select IF(0.1,1,0);
mysql& select IF(0.1&&0,1,0);
在上面的第一种情况中,IF(0.1)返回0,因为0.1被变换到整数值,
导致测试IF(0)。这可能不是你期望的。在第二种情况中,比较测试原来的浮点值看它是否是非零,比较的结果被用作一个整数。
CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...]
[ELSE result] END
CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result]
第一个版本返回result,其中value=compare-value。第二个版本中如果第一个条件为真,返回result。如果没有匹配的result值,那么结果在ELSE后的result被返回。如果没有ELSE部分,那么NULL被返回。
mysql& SELECT CASE 1 WHEN 1 THEN &one& WHEN 2 THEN &two& ELSE &more& END;
mysql& SELECT CASE WHEN 1&0 THEN &true& ELSE &false& END;
mysql& SELECT CASE BINARY &B& when &a& then 1 when &b& then 2 END;
所有的数学函数在一个出错的情况下返回NULL。
单目减。改变参数的符号。
mysql& select - 2;
注意,如果这个操作符与一个BIGINT使用,返回值是一个BIGINT!这意味着你应该避免在整数上使用-,那可能有值-2^63!
返回X的绝对值。 mysql& select ABS(2);
mysql& select ABS(-32);
该功能可安全用于BIGINT值。
返回参数的符号,为-1、0或1,取决于X是否是负数、零或正数。
mysql& select SIGN(-32);
mysql& select SIGN(0);
mysql& select SIGN(234);
模 (类似C中的%操作符)。返回N被M除的余数。
mysql& select MOD(234, 10);
mysql& select 253 % 7;
mysql& select MOD(29,9);
这个函数可安全用于BIGINT值。
返回不大于X的最大整数值。
mysql& select FLOOR(1.23);
mysql& select FLOOR(-1.23);
注意返回值被变换为一个BIGINT!
CEILING(X)
返回不小于X的最小整数值。 mysql& select CEILING(1.23);
mysql& select CEILING(-1.23);
注意返回值被变换为一个BIGINT!
返回参数X的四舍五入的一个整数。 mysql& select ROUND(-1.23);
mysql& select ROUND(-1.58);
mysql& select ROUND(1.58);
注意返回值被变换为一个BIGINT!
ROUND(X,D)
返回参数X的四舍五入的有D为小数的一个数字。如果D为0,结果将没有小数点或小数部分。
mysql& select ROUND(1.298, 1);
mysql& select ROUND(1.298, 0);
注意返回值被变换为一个BIGINT!
返回值e(自然对数的底)的X次方。 mysql& select EXP(2);
-& 7.389056
mysql& select EXP(-2);
-& 0.135335
返回X的自然对数。 mysql& select LOG(2);
-& 0.693147
mysql& select LOG(-2);
如果你想要一个数字X的任意底B的对数,使用公式LOG(X)/LOG(B)。
返回X的以10为底的对数。 mysql& select LOG10(2);
-& 0.301030
mysql& select LOG10(100);
-& 2.000000
mysql& select LOG10(-100);
POWER(X,Y)
返回值X的Y次幂。 mysql& select POW(2,2);
-& 4.000000
mysql& select POW(2,-2);
-& 0.250000
返回非负数X的平方根。 mysql& select SQRT(4);
-& 2.000000
mysql& select SQRT(20);
-& 4.472136
返回PI的值(圆周率)。 mysql& select PI();
-& 3.141593
返回X的余弦, 在这里X以弧度给出。 mysql& select COS(PI());
-& -1.000000
返回X的正弦值,在此X以弧度给出。 mysql& select SIN(PI());
-& 0.000000
返回X的正切值,在此X以弧度给出。 mysql& select TAN(PI()+1);
-& 1.557408
返回X反余弦,即其余弦值是X。如果X不在-1到1的范围,返回NULL。
mysql& select ACOS(1);
-& 0.000000
mysql& select ACOS(1.0001);
mysql& select ACOS(0);
-& 1.570796
返回X反正弦值,即其正弦值是X。L如果X不在-1到1的范围,返回NULL。
mysql& select ASIN(0.2);
-& 0.201358
mysql& select ASIN('foo');
-& 0.000000
返回X的反正切值,即其正切值是X。 mysql& select ATAN(2);
-& 1.107149
mysql& select ATAN(-2);
-& -1.107149
ATAN2(X,Y)
返回2个变量X和Y的反正切。它类似于计算Y/X的反正切,除了两个参数的符号被用来决定结果的象限。
mysql& select ATAN(-2,2);
-& -0.785398
mysql& select ATAN(PI(),0);
-& 1.570796
返回X的余切。 mysql& select COT(12);
mysql& select COT(0);
返回在范围0到1.0内的随机浮点值。如果一个整数参数N被指定,它被用作种子值。
mysql& select RAND();
mysql& select RAND(20);
mysql& select RAND(20);
mysql& select RAND();
mysql& select RAND();
你不能在一个ORDER BY子句用RAND()值使用列,因为ORDER
BY将重复计算列多次。然而在MySQL3.23中,你可以做:
SELECT * FROM table_name ORDER BY RAND(),这是有利于得到一个来自SELECT
* FROM table1,table2 WHERE a=b AND c&d ORDER BY RAND() LIMIT 1000的集合的随机样本。注意在一个WHERE子句里的一个RAND()将在每次WHERE被执行时重新评估。
LEAST(X,Y,...)
有2和2个以上的参数,返回最小(最小值)的参数。参数使用下列规则进行比较:
如果返回值被使用在一个INTEGER上下文,或所有的参数都是整数值,他们作为整数比较。
如果返回值被使用在一个REAL上下文,或所有的参数是实数值,他们作为实数比较。
如果任何参数是一个大小敏感的字符串,参数作为大小写敏感的字符串被比较。
在其他的情况下,参数作为大小写无关的字符串被比较。
mysql& select LEAST(2,0);
mysql& select LEAST(34.0,3.0,5.0,767.0);
mysql& select LEAST(&B&,&A&,&C&);
在MySQL 3.22.5以前的版本,你可以使用MIN()而不是LEAST。
GREATEST(X,Y,...)
返回最大(最大值)的参数。参数使用与LEAST一样的规则进行比较。
mysql& select GREATEST(2,0);
mysql& select GREATEST(34.0,3.0,5.0,767.0);
mysql& select GREATEST(&B&,&A&,&C&);
在MySQL在 3.22.5 以前的版本, 你能使用MAX()而不是GREATEST.
DEGREES(X)
返回参数X,从弧度变换为角度。 mysql& select DEGREES(PI());
-& 180.000000
RADIANS(X)
返回参数X,从角度变换为弧度。 mysql& select RADIANS(90);
-& 1.570796
TRUNCATE(X,D)
返回数字X,截断为D位小数。如果D为0,结果将没有小数点或小数部分。
mysql& select TRUNCATE(1.223,1);
mysql& select TRUNCATE(1.999,1);
mysql& select TRUNCATE(1.999,0);
如果结果的长度大于服务器参数max_allowed_packet,字符串值函数返回NULL。见。
对于针对字符串位置的操作,第一个位置被标记为1。
ASCII(str)
返回字符串str的最左面字符的ASCII代码值。如果str是空字符串,返回0。如果str是NULL,返回NULL。
mysql& select ASCII('2');
mysql& select ASCII(2);
mysql& select ASCII('dx');
也可参见ORD()函数。
如果字符串str最左面字符是一个多字节字符,通过以格式((first
byte ASCII code)*256+(second byte ASCII code))[*256+third byte ASCII code...]返回字符的ASCII代码值来返回多字节字符代码。如果最左面的字符不是一个多字节字符。返回与ASCII()函数返回的相同值。mysql& select ORD('2');
CONV(N,from_base,to_base)
在不同的数字基之间变换数字。返回数字N的字符串数字,从from_base基变换为to_base基,如果任何参数是NULL,返回NULL。参数N解释为一个整数,但是可以指定为一个整数或一个字符串。最小基是2且最大的基是36。如果to_base是一个负数,N被认为是一个有符号数,否则,N被当作无符号数。
CONV以64位点精度工作。 mysql& select CONV(&a&,16,2);
mysql& select CONV(&6E&,18,8);
mysql& select CONV(-17,10,-18);
mysql& select CONV(10+&10&+'10'+0xa,10,10);
返回二进制值N的一个字符串表示,在此N是一个长整数(BIGINT)数字,这等价于CONV(N,10,2)。如果N是NULL,返回NULL。
mysql& select BIN(12);
返回八进制值N的一个字符串的表示,在此N是一个长整型数字,这等价于CONV(N,10,8)。如果N是NULL,返回NULL。
mysql& select OCT(12);
返回十六进制值N一个字符串的表示,在此N是一个长整型(BIGINT)数字,这等价于CONV(N,10,16)。如果N是NULL,返回NULL。
mysql& select HEX(255);
CHAR(N,...)
CHAR()将参数解

我要回帖

更多关于 字符串输出函数 的文章

 

随机推荐