mysql中的null字段值的处理及大小写问题

在MySQL中,NULL字段的处理,需要注意,当在处理查询条件中有NULL,很有可能你得到的值不是想要的,因为,在MySQL中,判断NULL值相等(=)或者不等(!=)都会返回false。主要出现在常见的SELECT以及WHERE字句中。

为了处理这种特殊的情况,MySQL提供了如下的关键字进行特殊处理:

  • IS NULL: 当列的值是NULL,此运算符返回true。
  • IS NOT NULL: 当列的值不为NULL, 运算符返回true。
  • <=>: 比较操作符(不同于=运算符),当比较的的两个值为NULL时返回true。

关于 NULL 的条件比较运算是比较特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。
在MySQL中,NULL值与任何其它值的比较(即使是NULL)永远返回false,即 NULL = NULL 返回false 。

下面看看例子,就很清楚的理解是什么意思了。

先在test数据库中创建一个表checknull。

1 mysql> use test
2 Database changed
3 mysql> show tables;
4 Empty set (0.00 sec)
5
6 mysql> create table checknull(
7     -> name varchar(30) not null,
8     -> age int);
9 Query OK, 0 rows affected (0.11 sec)

我们看看这个表的创建基本信息,用show和desc分别查看:

 1 mysql> show create table checknull;
 2 +-----------+-------------------------------------------------------------------------------------------------------------------------------+
 3 | Table     | Create Table                                                                                                                  |
 4 +-----------+-------------------------------------------------------------------------------------------------------------------------------+
 5 | checknull | CREATE TABLE `checknull` (
 6   `name` varchar(30) NOT NULL,
 7   `age` int(11) DEFAULT NULL
 8 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
 9 +-----------+-------------------------------------------------------------------------------------------------------------------------------+
10 1 row in set (0.01 sec)
11
12 mysql> desc checknull;
13 +-------+-------------+------+-----+---------+-------+
14 | Field | Type        | Null | Key | Default | Extra |
15 +-------+-------------+------+-----+---------+-------+
16 | name  | varchar(30) | NO   |     | NULL    |       |
17 | age   | int(11)     | YES  |     | NULL    |       |
18 +-------+-------------+------+-----+---------+-------+
19 2 rows in set (0.00 sec)

我们开始测试一下,第一步,向这个表中插入数据:

 1 mysql> insert checknull (name, age) values("water", 30);
 2 Query OK, 1 row affected (0.00 sec)
 3
 4 mysql>
 5 mysql> insert checknull (name, age) values("shihuc", NULL);
 6 Query OK, 1 row affected (0.00 sec)
 7
 8 mysql>
 9 mysql> select * from checknull;
10 +--------+------+
11 | name   | age  |
12 +--------+------+
13 | water  |   30 |
14 | shihuc | NULL |
15 +--------+------+
16 2 rows in set (0.00 sec)

接下来,再查询看看,先查询所有的age字段是NULL的用户信息:

 1 mysql> select * from checknull where age = NULL;
 2 Empty set (0.00 sec)
 3
 4 mysql> select * from checknull where age IS NULL;
 5 +--------+------+
 6 | name   | age  |
 7 +--------+------+
 8 | shihuc | NULL |
 9 +--------+------+
10 1 row in set (0.00 sec)

 1 mysql> select * from checknull where age != NULL;
 2 Empty set (0.00 sec)
 3
 4 mysql> select * from checknull where age IS NOT NULL;
 5 +-------+------+
 6 | name  | age  |
 7 +-------+------+
 8 | water |   30 |
 9 +-------+------+
10 1 row in set (0.00 sec)

是不是发现,结果不同?那么我现在,通过修改大小写来查看查询结果:

 1 mysql> select * from checknull where age IS null;
 2 +--------+------+
 3 | name   | age  |
 4 +--------+------+
 5 | shihuc | NULL |
 6 +--------+------+
 7 1 row in set (0.00 sec)
 8
 9 mysql> select * from checknull where age = null;
10 Empty set (0.00 sec)

 1 mysql> select * from checknull where age != null;
 2 Empty set (0.00 sec)
 3
 4 mysql> select * from checknull where age is not null;
 5 +-------+------+
 6 | name  | age  |
 7 +-------+------+
 8 | water |   30 |
 9 +-------+------+
10 1 row in set (0.00 sec)

发现结果和上面的日志反映的内容一样。

这里补充一个小tips,那就是在Linux下,mysql默认情况下,数据库的名字,表的名字和字段的名字是区分大小写的,但是字段的值是不区分大小写的

表的名字和字段的名字是否区分大小写,可以查看数据库变量lower_case_table_names的值,0表示区分大小写;1表示不区分,统一按照小写对待。

1 mysql> show variables like "%case%";
2 +------------------------+-------+
3 | Variable_name          | Value |
4 +------------------------+-------+
5 | lower_case_file_system | OFF   |
6 | lower_case_table_names | 0     |
7 +------------------------+-------+
8 2 rows in set (0.00 sec)

而对于字段的值,想要区分大小写,可以使用BINARY加以限制。不管是在创建表的时候,还是在查询的条件字句中都可以使用。

 1 mysql> create table lowupper(
 2     -> name varchar(30) not null,
 3     -> age int,
 4     -> home varchar(40) binary);
 5 Query OK, 0 rows affected (0.10 sec)
 6
 7 mysql> show create table lowupper;
 8 +----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 9 | Table    | Create Table                                                                                                                                                                                            |
10 +----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
11 | lowupper | CREATE TABLE `lowupper` (
12   `name` varchar(30) NOT NULL,
13   `age` int(11) DEFAULT NULL,
14   `home` varchar(40) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL
15 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
16 +----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
17 1 row in set (0.00 sec)

上面日志中,可以看到,创建表的时候,

在home字段后面加了约束binary,通过show可以看到,home字段有一个校对规则 latin1_bin
说明,这个会在插入/查询数据的时候是区分大小写的。

下面插入数据做些验证:

 1 mysql> insert lowupper (name, age, home) values ("shihuc", 30, "Beijing, china");
 2 Query OK, 1 row affected (0.00 sec)
 3
 4 mysql>
 5 mysql> insert lowupper (name, age, home) values ("water", 33, "BEIJING, china");
 6 Query OK, 1 row affected (0.00 sec)
 7
 8 mysql> insert lowupper (name, age, home) values ("xiaocheng", 33, "hubei");
 9 Query OK, 1 row affected (0.00 sec)
10
11 mysql> insert lowupper (name, age, home) values ("zhangsan", null, "china");
12 Query OK, 1 row affected (0.00 sec)
13
14 mysql> insert lowupper (name, age, home) values ("lisi", null, "CHINA");
15 Query OK, 1 row affected (0.00 sec)
16
17 mysql> insert lowupper (name, age, home) values ("wangwu", null, "China");
18 Query OK, 1 row affected (0.00 sec)
19
20 mysql> select * from lowupper;
21 +-----------+------+----------------+
22 | name      | age  | home           |
23 +-----------+------+----------------+
24 | shihuc    |   30 | Beijing, china |
25 | water     |   33 | BEIJING, china |
26 | xiaocheng |   33 | hubei          |
27 | zhangsan  | NULL | china          |
28 | lisi      | NULL | CHINA          |
29 | wangwu    | NULL | China          |
30 +-----------+------+----------------+
31 6 rows in set (0.00 sec)

下面,再查询一下看看,是否有区分:

1 mysql> select * from lowupper where home = "china";
2 +----------+------+-------+
3 | name     | age  | home  |
4 +----------+------+-------+
5 | zhangsan | NULL | china |
6 +----------+------+-------+
7 1 row in set (0.00 sec)

再操作上面checknull表,在其中插入一条新的数据,进行查询,看是否区分大小写:

 1 mysql> insert checknull (name, age) values ("SHIHUC", null);
 2 Query OK, 1 row affected (0.00 sec)
 3
 4 mysql> select * from checknull;
 5 +--------+------+
 6 | name   | age  |
 7 +--------+------+
 8 | water  |   30 |
 9 | shihuc | NULL |
10 | SHIHUC | NULL |
11 +--------+------+
12 3 rows in set (0.00 sec)
13
14 mysql> select * from checknull where name = "shihuc";
15 +--------+------+
16 | name   | age  |
17 +--------+------+
18 | shihuc | NULL |
19 | SHIHUC | NULL |
20 +--------+------+
21 2 rows in set (0.00 sec)
22
23 mysql> select * from checknull where binary name = "shihuc";
24 +--------+------+
25 | name   | age  |
26 +--------+------+
27 | shihuc | NULL |
28 +--------+------+
29 1 row in set (0.00 sec)

是不是很显然的,说明MySQL的大小写问题,还是很有意思的,需要注意,在linux环境下。windows环境下,没有测试,不是很确定。有经验的可以分享一下!

http://www.cnblogs.com/shihuc/p/5165169.html

时间: 2024-08-01 18:48:23

mysql中的null字段值的处理及大小写问题的相关文章

Mysql中自增字段(AUTO_INCREMENT)的一些常识

Mysql中自增字段(AUTO_INCREMENT)的一些常识 在系统开发过程中,我们经常要用到唯一编号.使用过mysql的人都应该知道,mysql有一个定义列为自增的属性:AUTO_INCREMENT. 指定了AUTO_INCREMENT的列必须要建索引,不然会报错,索引可以为主键索引,当然也可以为非主键索引.(不一定要做主键) 1 2 3 mysql> create table t4 (id int auto_increment); ERROR 1075 (42000): Incorrect

mysql中多个字段共同确定唯一性

create table tbl_table ( id integer not null auto_increment, fname varchar(255), lname varchar(255), CONSTRAINT tbl_table PRIMARY KEY (id), unique (fname,lname) ) mysql中多个字段共同确定唯一性

使用LINQ获取List列表中的某个字段值

使用LINQ获取列表中的某个字段值,下面以获取员工列表中的编号字段为例子. 1.使用Select方法 1 List<Emplayee> emplayeeList = GetEmplayeeList(); //获取员工信息列表 2 int[] empIds = emplayeeList.Select(a => a.Id).ToArray(); //获取员工编号数组 2.使用ForEach方法 1 List<Emplayee> emplayeeList = GetEmplayee

SqlServer和MySQL中存储过程out返回值处理C#代码

1.SqlServer中out处理 C#代码 #region"SqlServer中存储过程处理out返回值" //public void getdata() //{ // string str = " server=192.168.xxxx ;user id=xxx;[email protected]#;database=xxxxx_db;min pool size=4;max pool size=4;packet size=3072"; // SqlConnect

查询某个分组中多行字段值的拼接字串的方法--access

查询某个分组中多行字段值的拼接字串的方法 先收藏,后面再研究 access的SQL语法中没有自定义函数,也不能象SQL Server中一样用变量.游标.子查询等方法来灵活处理查询语句. 但是,在Access环境中,透过模块中的过程,可利用功能强大的VB语言,生成复杂需求的查询语句. 下面是本人今天在Access版块中的一个回复,以此例 access的SQL语法中没有自定义函数,也不能象SQL Server中一样用变量.游标.子查询等方法来灵活处理查询语句. 但是,在Access环境中,透过模块中

mysql中的保留字段

摘要 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server versio····这句话对于咱们并不陌生,无非就是多了","之类的问题.但是你如果无意之中添加了一个mysql中的保留字段作为数据库中存贮的字段名,悲剧就这样发生了. mysql 保留字 目录[-] mysql的保留字段 前几天因为功能的临时变更,需要给数据表添加一个字段用来区别导入的批次,我就

C#三种判断数据库中取出的字段值是否为空(NULL) 的方法

最近操作数据库,需要判断返回的字段值是否为空,在网上收集了3种方法供大家参考 1 通过System.DBNull判断,网上大部分都使用这个方法. 复制代码代码如下: DataTable dt;                               //假设字段为name, dt已经保存了数据dt.rows[0]["name"] == System.DBNull.Value;  //判断第一行数据的name字段是否为空 2 通过IsNull判断 复制代码代码如下: DataTabl

Mysql 中is null 和 =null 的区别

在mysql中,筛选非空的时候经常会用到is not null和!=null,这两种方法单从字面上来看感觉是差不多的,其实如 果去运行一下试试的话差别会很大! 为什么会出现这种情况呢? null 表示什么也不是, 不能=.>.< … 所有的判断,结果都是false,所有只能用 is null进行判断.默认情况下,推荐使用 IS NOT NULL去判断,因为SQL默认情况下对!= Null的判断会永远返回0行,但没有语法错误 .如果你一定想要使用!= Null来判断,需要加上这个语句: set

mysql中的保留字段,说多了都是泪啊!!!!

前几天因为功能的临时变更,需要给数据表添加一个字段用来区别导入的批次,我就在mysql中添加了group字段,没想到我的噩梦就此展开····· 本来程序已经接近收尾,本想着今早来公司给程序来个欢乐的结尾,没想到····每次导入excel表总是提示我sql语句错误,我变在sql语句上添添减减,也没有把错误搞定,整整一个上午外加下午两个小时,简直已经到了抓狂的程度.简直要跪地苦思冥想,但是还是没有搞定这个错误. 把问题放在一边,继续搞其他的东西····当在写一个group by 语句时,突然意识到,