MySQL常见错误问答!
2007-11-11 13:51:52 来源:WEB开发网核心提示: 18.9 怎样重新设置一个忘记的口令 如果你忘记了MySQL(和PHP搭配之最佳组合)的root用户的口令,你可以用下列过程恢复它,MySQL常见错误问答!(3), 通过发送一个kill(不是kill -9)到MySQL(和PHP搭配之最佳组合)d服务器来关闭MySQL(和PHP搭配之最佳组合)d服务器,pid
18.9 怎样重新设置一个忘记的口令
如果你忘记了MySQL(和PHP搭配之最佳组合)的root用户的口令,你可以用下列过程恢复它。
通过发送一个kill(不是kill -9)到MySQL(和PHP搭配之最佳组合)d服务器来关闭MySQL(和PHP搭配之最佳组合)d服务器。pid 被保存在一个.pid文件中,通常在MySQL(和PHP搭配之最佳组合)数据库目录中:
kill `cat /MySQL(和PHP搭配之最佳组合)-data-directory/hostname.pid`
你必须是一个UNIX root用户或运行服务器的相同用户做这个。
使用--skip-grant-tables选项重启MySQL(和PHP搭配之最佳组合)d。
用MySQL(和PHP搭配之最佳组合) -h hostname MySQL(和PHP搭配之最佳组合)连接MySQL(和PHP搭配之最佳组合)d服务器并且用一条GRANT命令改变口令。见7.26 GRANT和REVOKE句法。你也可以用MySQL(和PHP搭配之最佳组合)admin -h hostname -u user password ’new password’ 进行。
用MySQL(和PHP搭配之最佳组合)admin -h hostname flush-privileges或用SQL命令FLUSH PRIVILEGES来装载权限表。
18.10 文件许可权限问题
如果你有与文件许可有关的问题,例如,如果当你创建一张表时,MySQL(和PHP搭配之最佳组合)发出下列错误消息:
ERROR: Can’t find file: ’path/with/filename.frm’ (Errcode: 13)
那么可能是在MySQL(和PHP搭配之最佳组合)d启动时,环境变量UMASK可能设置不正确。缺省的umask值是0660。你可以如下启动safe_MySQL(和PHP搭配之最佳组合)d改变其行为:
shell> UMASK=384 # = 600 in octal
shell> export UMASK
shell> /path/to/safe_MySQL(和PHP搭配之最佳组合)d &
18.11 文件没找到
如果你从MySQL(和PHP搭配之最佳组合)得到ERROR ’...’ not found (errno: 23), Can’t open file: ... (errno: 24)或任何其他有errno 23或errno 24的错误,它意味着,你没有为MySQL(和PHP搭配之最佳组合)分配足够的文件描述符。你能使用perror实用程序得到错误号含义是什么的描述:
shell> perror 23
File table overflow
shell> perror 24
Too many open files
这里的问题是MySQL(和PHP搭配之最佳组合)d正在试图同时保持打开太多的文件。你也可以告诉MySQL(和PHP搭配之最佳组合)d一次不打开那么多的文件,或增加MySQL(和PHP搭配之最佳组合)d可得到的文件描述符数量。为了告诉MySQL(和PHP搭配之最佳组合)d一次保持打开更少的文件,你可以通过使用safe_MySQL(和PHP搭配之最佳组合)d的-O table_cache=32选项(缺省值是64)使表缓冲更小。减小max_connections值也将减少打开文件的数量(缺省值是90)。
要想改变MySQL(和PHP搭配之最佳组合)d可用的文件描述符数量,修改safe_MySQL(和PHP搭配之最佳组合)d脚本。脚本中有一条注释了的行ulimit -n 256。你可以删除’#’字符来去掉该行的注释,并且改变数字256改变为MySQL(和PHP搭配之最佳组合)d可用的文件描述符的数量。
ulimit能增加文件描述符的数量,但是只能到操作系统强加的限制。如果你需要增加每个进程可用的文件描述符数量的OS限制,参见你的操作系统文档。注意,如果你运行tcsh外壳,ulimit将不工作!当你请求当前限制时,tcsh也将报告不正确的值!在这种情况下,你应该用sh启动safe_MySQL(和PHP搭配之最佳组合)d!
18.12 使用DATE列的问题
一个DATE值的格式是’YYYY-MM-DD’。根据ANSI SQL,不允许其他格式。你应该在UPDATE表达式和SELECT语句的WHERE子句中使用这个格式。例如:
MySQL(和PHP搭配之最佳组合)> SELECT * FROM tbl_name WHERE date >= ’1997-05-05’;
为了方便,如果日期用在数字上下文,MySQL(和PHP搭配之最佳组合)自动变换一个日期到一个数字(并且反过来也如此)。当更新时和将一个日期与TIMESTAMP、DATE或DATETIME列比较的一个WHERE子句中,也是足够灵活以允许一种“宽松”的字符串格式。(宽松格式意味着任何标点字符用作在部件之间的分割符。例如,’1998-08-15’和’1998#08#15’是等价的。)MySQL(和PHP搭配之最佳组合)也能变换不包含分割符的一个字符串(例如 ’19980815’),如果它作为一个日期说得通。特殊日期’0000-00-00’可以作为’0000-00-00’被存储和检索。当通过MyODBC使用一个’0000-00-00’日期时,在MyODBC 2.50.12和以上版本,它将自动被转换为NULL,因为ODBC不能处理这种日期。
因为MySQL(和PHP搭配之最佳组合)实行了上述的变换,下列语句可以工作:
MySQL(和PHP搭配之最佳组合)> INSERT INTO tbl_name (idate) VALUES (19970505);
MySQL(和PHP搭配之最佳组合)> INSERT INTO tbl_name (idate) VALUES (’19970505’);
MySQL(和PHP搭配之最佳组合)> INSERT INTO tbl_name (idate) VALUES (’97-05-05’);
MySQL(和PHP搭配之最佳组合)> INSERT INTO tbl_name (idate) VALUES (’1997.05.05’);
MySQL(和PHP搭配之最佳组合)> INSERT INTO tbl_name (idate) VALUES (’1997 05 05’);
MySQL(和PHP搭配之最佳组合)> INSERT INTO tbl_name (idate) VALUES (’0000-00-00’);
MySQL(和PHP搭配之最佳组合)> SELECT idate FROM tbl_name WHERE idate >= ’1997-05-05’;
MySQL(和PHP搭配之最佳组合)> SELECT idate FROM tbl_name WHERE idate >= 19970505;
MySQL(和PHP搭配之最佳组合)> SELECT mod(idate,100) FROM tbl_name WHERE idate >= 19970505;
MySQL(和PHP搭配之最佳组合)> SELECT idate FROM tbl_name WHERE idate >= ’19970505’;
然而,下列将不工作:
MySQL(和PHP搭配之最佳组合)> SELECT idate FROM tbl_name WHERE STRCMP(idate,’19970505’)=0;
STRCMP()是字符串函数,因此它将idate转换为一个字符串并且实施字符串比较。它不将’19970505’转换为一个日期并实施日期比较。
注意,MySQL(和PHP搭配之最佳组合)不检查日期是否正确。如果你存储一个不正确的日期,例如’1998-2-31’,错误的日期将被存储。如果日期不能被变换到任何合理的值,在DATE字段中存储一个0。这主要是一个速度问题并且我们认为检查日期是应用程序的责任,而不服务器。
18.13 时区问题
如果你有一个问题,SELECT NOW()以GMT时间返回值而不是你的本地时间,你必须设定TZ环境变量为你的当前时区。这应该在服务器运行的环境进行,例如在safe_MySQL(和PHP搭配之最佳组合)d或MySQL(和PHP搭配之最佳组合).server中。
18.14 在搜索中的大小写敏感性
缺省地,MySQL(和PHP搭配之最佳组合)搜索是大小写不敏感的(尽管有一些字符集从来不是忽略大小写的,例如捷克语)。这意味着,如果你用col_name LIKE ’a%’搜寻,你将得到所有以A或a开始的列值。如果你想要使这个搜索大小写敏感,使用象INDEX(col_name, "A")=0检查一个前缀。或如果列值必须确切是"A",使用STRCMP(col_name, "A") = 0。
简单的比较操作(>=、>、= 、< 、<=、排序和聚合)是基于每个字符的“排序值”。有同样排序值的字符(象E,e和’e)被视为相同的字符!
LIKE比较在每个字符的大写值上进行(E==e 但是E<>’e)。
如果你想要一个列总是被当作大小写敏感的方式,声明它为BINARY。见7.7 CREATE TABLE句法。
如果你使用以所谓的big5编码的中文数据,你要使所有的字符列是BINARY,它可行,是因为big5编码字符的排序顺序基于 ASCII代码的顺序。
18.15 NULL值问题
NULL值的概念是造成SQL的新手的混淆的普遍原因,他们经常认为NULL是和一个空字符串’’的一样的东西。不是这样的!例如,下列语句是完全不同的:
MySQL(和PHP搭配之最佳组合)> INSERT INTO my_table (phone) VALUES (NULL);
MySQL(和PHP搭配之最佳组合)> INSERT INTO my_table (phone) VALUES ("");
两个语句把值插入到phone列,但是第一个插入一个NULL值而第二个插入一个空字符串。第一个的含义可以认为是“电话号码不知道”,而第二个则可意味着“她没有电话”。
在SQL中,NULL值在于任何其他值甚至NULL值比较时总是假的(FALSE)。包含NULL的一个表达式总是产生一个NULL值,除非在包含在表达式中的运算符和函数的文档中指出。在下列例子,所有的列返回NULL:
MySQL(和PHP搭配之最佳组合)> SELECT NULL,1+NULL,CONCAT(’Invisible’,NULL);
如果你想要寻找值是NULL的列,你不能使用=NULL测试。下列语句不返回任何行,因为对任何表达式,expr = NULL是假的:
MySQL(和PHP搭配之最佳组合)> SELECT * FROM my_table WHERE phone = NULL;
要想寻找NULL值,你必须使用IS NULL测试。下例显示如何找出NULL电话号码和空的电话号码:
MySQL(和PHP搭配之最佳组合)> SELECT * FROM my_table WHERE phone IS NULL;
MySQL(和PHP搭配之最佳组合)> SELECT * FROM my_table WHERE phone = "";
在MySQL(和PHP搭配之最佳组合)中,就像很多其他的SQL服务器一样,你不能索引可以有NULL值的列。你必须声明这样的列为NOT NULL,而且,你不能插入NULL到索引的列中。当用LOAD DATA INFILE读取数据时,空列用’’更新。如果你想要在一个列中有NULL值,你应该在文本文件中使用\N。字面词’NULL’也可以在某些情形下使用。见7.16 LOAD DATA INFILE句法。当使用ORDER BY时,首先呈现NULL值。如果你用DESC以降序排序,NULL值最后显示。当使用GROUP BY时,所有的NULL值被认为是相等的。为了有助于NULL的处理,你能使用IS NULL和IS NOT NULL运算符和IFNULL()函数。
对某些列类型,NULL值被特殊地处理。如果你将NULL插入表的第一个TIMESTAMP列,则插入当前的日期和时间。如果你将NULL插入一个AUTO_INCREMENT列,则插入顺序中的下一个数字。
如果你忘记了MySQL(和PHP搭配之最佳组合)的root用户的口令,你可以用下列过程恢复它。
通过发送一个kill(不是kill -9)到MySQL(和PHP搭配之最佳组合)d服务器来关闭MySQL(和PHP搭配之最佳组合)d服务器。pid 被保存在一个.pid文件中,通常在MySQL(和PHP搭配之最佳组合)数据库目录中:
kill `cat /MySQL(和PHP搭配之最佳组合)-data-directory/hostname.pid`
你必须是一个UNIX root用户或运行服务器的相同用户做这个。
使用--skip-grant-tables选项重启MySQL(和PHP搭配之最佳组合)d。
用MySQL(和PHP搭配之最佳组合) -h hostname MySQL(和PHP搭配之最佳组合)连接MySQL(和PHP搭配之最佳组合)d服务器并且用一条GRANT命令改变口令。见7.26 GRANT和REVOKE句法。你也可以用MySQL(和PHP搭配之最佳组合)admin -h hostname -u user password ’new password’ 进行。
用MySQL(和PHP搭配之最佳组合)admin -h hostname flush-privileges或用SQL命令FLUSH PRIVILEGES来装载权限表。
18.10 文件许可权限问题
如果你有与文件许可有关的问题,例如,如果当你创建一张表时,MySQL(和PHP搭配之最佳组合)发出下列错误消息:
ERROR: Can’t find file: ’path/with/filename.frm’ (Errcode: 13)
那么可能是在MySQL(和PHP搭配之最佳组合)d启动时,环境变量UMASK可能设置不正确。缺省的umask值是0660。你可以如下启动safe_MySQL(和PHP搭配之最佳组合)d改变其行为:
shell> UMASK=384 # = 600 in octal
shell> export UMASK
shell> /path/to/safe_MySQL(和PHP搭配之最佳组合)d &
18.11 文件没找到
如果你从MySQL(和PHP搭配之最佳组合)得到ERROR ’...’ not found (errno: 23), Can’t open file: ... (errno: 24)或任何其他有errno 23或errno 24的错误,它意味着,你没有为MySQL(和PHP搭配之最佳组合)分配足够的文件描述符。你能使用perror实用程序得到错误号含义是什么的描述:
shell> perror 23
File table overflow
shell> perror 24
Too many open files
这里的问题是MySQL(和PHP搭配之最佳组合)d正在试图同时保持打开太多的文件。你也可以告诉MySQL(和PHP搭配之最佳组合)d一次不打开那么多的文件,或增加MySQL(和PHP搭配之最佳组合)d可得到的文件描述符数量。为了告诉MySQL(和PHP搭配之最佳组合)d一次保持打开更少的文件,你可以通过使用safe_MySQL(和PHP搭配之最佳组合)d的-O table_cache=32选项(缺省值是64)使表缓冲更小。减小max_connections值也将减少打开文件的数量(缺省值是90)。
要想改变MySQL(和PHP搭配之最佳组合)d可用的文件描述符数量,修改safe_MySQL(和PHP搭配之最佳组合)d脚本。脚本中有一条注释了的行ulimit -n 256。你可以删除’#’字符来去掉该行的注释,并且改变数字256改变为MySQL(和PHP搭配之最佳组合)d可用的文件描述符的数量。
ulimit能增加文件描述符的数量,但是只能到操作系统强加的限制。如果你需要增加每个进程可用的文件描述符数量的OS限制,参见你的操作系统文档。注意,如果你运行tcsh外壳,ulimit将不工作!当你请求当前限制时,tcsh也将报告不正确的值!在这种情况下,你应该用sh启动safe_MySQL(和PHP搭配之最佳组合)d!
18.12 使用DATE列的问题
一个DATE值的格式是’YYYY-MM-DD’。根据ANSI SQL,不允许其他格式。你应该在UPDATE表达式和SELECT语句的WHERE子句中使用这个格式。例如:
MySQL(和PHP搭配之最佳组合)> SELECT * FROM tbl_name WHERE date >= ’1997-05-05’;
为了方便,如果日期用在数字上下文,MySQL(和PHP搭配之最佳组合)自动变换一个日期到一个数字(并且反过来也如此)。当更新时和将一个日期与TIMESTAMP、DATE或DATETIME列比较的一个WHERE子句中,也是足够灵活以允许一种“宽松”的字符串格式。(宽松格式意味着任何标点字符用作在部件之间的分割符。例如,’1998-08-15’和’1998#08#15’是等价的。)MySQL(和PHP搭配之最佳组合)也能变换不包含分割符的一个字符串(例如 ’19980815’),如果它作为一个日期说得通。特殊日期’0000-00-00’可以作为’0000-00-00’被存储和检索。当通过MyODBC使用一个’0000-00-00’日期时,在MyODBC 2.50.12和以上版本,它将自动被转换为NULL,因为ODBC不能处理这种日期。
因为MySQL(和PHP搭配之最佳组合)实行了上述的变换,下列语句可以工作:
MySQL(和PHP搭配之最佳组合)> INSERT INTO tbl_name (idate) VALUES (19970505);
MySQL(和PHP搭配之最佳组合)> INSERT INTO tbl_name (idate) VALUES (’19970505’);
MySQL(和PHP搭配之最佳组合)> INSERT INTO tbl_name (idate) VALUES (’97-05-05’);
MySQL(和PHP搭配之最佳组合)> INSERT INTO tbl_name (idate) VALUES (’1997.05.05’);
MySQL(和PHP搭配之最佳组合)> INSERT INTO tbl_name (idate) VALUES (’1997 05 05’);
MySQL(和PHP搭配之最佳组合)> INSERT INTO tbl_name (idate) VALUES (’0000-00-00’);
MySQL(和PHP搭配之最佳组合)> SELECT idate FROM tbl_name WHERE idate >= ’1997-05-05’;
MySQL(和PHP搭配之最佳组合)> SELECT idate FROM tbl_name WHERE idate >= 19970505;
MySQL(和PHP搭配之最佳组合)> SELECT mod(idate,100) FROM tbl_name WHERE idate >= 19970505;
MySQL(和PHP搭配之最佳组合)> SELECT idate FROM tbl_name WHERE idate >= ’19970505’;
然而,下列将不工作:
MySQL(和PHP搭配之最佳组合)> SELECT idate FROM tbl_name WHERE STRCMP(idate,’19970505’)=0;
STRCMP()是字符串函数,因此它将idate转换为一个字符串并且实施字符串比较。它不将’19970505’转换为一个日期并实施日期比较。
注意,MySQL(和PHP搭配之最佳组合)不检查日期是否正确。如果你存储一个不正确的日期,例如’1998-2-31’,错误的日期将被存储。如果日期不能被变换到任何合理的值,在DATE字段中存储一个0。这主要是一个速度问题并且我们认为检查日期是应用程序的责任,而不服务器。
18.13 时区问题
如果你有一个问题,SELECT NOW()以GMT时间返回值而不是你的本地时间,你必须设定TZ环境变量为你的当前时区。这应该在服务器运行的环境进行,例如在safe_MySQL(和PHP搭配之最佳组合)d或MySQL(和PHP搭配之最佳组合).server中。
18.14 在搜索中的大小写敏感性
缺省地,MySQL(和PHP搭配之最佳组合)搜索是大小写不敏感的(尽管有一些字符集从来不是忽略大小写的,例如捷克语)。这意味着,如果你用col_name LIKE ’a%’搜寻,你将得到所有以A或a开始的列值。如果你想要使这个搜索大小写敏感,使用象INDEX(col_name, "A")=0检查一个前缀。或如果列值必须确切是"A",使用STRCMP(col_name, "A") = 0。
简单的比较操作(>=、>、= 、< 、<=、排序和聚合)是基于每个字符的“排序值”。有同样排序值的字符(象E,e和’e)被视为相同的字符!
LIKE比较在每个字符的大写值上进行(E==e 但是E<>’e)。
如果你想要一个列总是被当作大小写敏感的方式,声明它为BINARY。见7.7 CREATE TABLE句法。
如果你使用以所谓的big5编码的中文数据,你要使所有的字符列是BINARY,它可行,是因为big5编码字符的排序顺序基于 ASCII代码的顺序。
18.15 NULL值问题
NULL值的概念是造成SQL的新手的混淆的普遍原因,他们经常认为NULL是和一个空字符串’’的一样的东西。不是这样的!例如,下列语句是完全不同的:
MySQL(和PHP搭配之最佳组合)> INSERT INTO my_table (phone) VALUES (NULL);
MySQL(和PHP搭配之最佳组合)> INSERT INTO my_table (phone) VALUES ("");
两个语句把值插入到phone列,但是第一个插入一个NULL值而第二个插入一个空字符串。第一个的含义可以认为是“电话号码不知道”,而第二个则可意味着“她没有电话”。
在SQL中,NULL值在于任何其他值甚至NULL值比较时总是假的(FALSE)。包含NULL的一个表达式总是产生一个NULL值,除非在包含在表达式中的运算符和函数的文档中指出。在下列例子,所有的列返回NULL:
MySQL(和PHP搭配之最佳组合)> SELECT NULL,1+NULL,CONCAT(’Invisible’,NULL);
如果你想要寻找值是NULL的列,你不能使用=NULL测试。下列语句不返回任何行,因为对任何表达式,expr = NULL是假的:
MySQL(和PHP搭配之最佳组合)> SELECT * FROM my_table WHERE phone = NULL;
要想寻找NULL值,你必须使用IS NULL测试。下例显示如何找出NULL电话号码和空的电话号码:
MySQL(和PHP搭配之最佳组合)> SELECT * FROM my_table WHERE phone IS NULL;
MySQL(和PHP搭配之最佳组合)> SELECT * FROM my_table WHERE phone = "";
在MySQL(和PHP搭配之最佳组合)中,就像很多其他的SQL服务器一样,你不能索引可以有NULL值的列。你必须声明这样的列为NOT NULL,而且,你不能插入NULL到索引的列中。当用LOAD DATA INFILE读取数据时,空列用’’更新。如果你想要在一个列中有NULL值,你应该在文本文件中使用\N。字面词’NULL’也可以在某些情形下使用。见7.16 LOAD DATA INFILE句法。当使用ORDER BY时,首先呈现NULL值。如果你用DESC以降序排序,NULL值最后显示。当使用GROUP BY时,所有的NULL值被认为是相等的。为了有助于NULL的处理,你能使用IS NULL和IS NOT NULL运算符和IFNULL()函数。
对某些列类型,NULL值被特殊地处理。如果你将NULL插入表的第一个TIMESTAMP列,则插入当前的日期和时间。如果你将NULL插入一个AUTO_INCREMENT列,则插入顺序中的下一个数字。
更多精彩
赞助商链接