设为首页 加入收藏

TOP

SQL中的null(一)
2015-11-21 01:51:20 来源: 作者: 【 】 浏览:2
Tags:SQL null

对Oracle SQL中的null小结如下:

1.1 null

? null 值计算的结果仍是null

? null 是一个未分配的、未知的,或不适用的值

? null不是0,也不是空格

?

1.1.1 null值的运算

null参数的算术表达式的结果仍然为null

SQL> select '*'||1/null||'*' res1,'*'||1*null||'*' res2, '*'||(1-null)||'*' res3 from dual;

RE RE RE

-- -- --

** ** **

SQL>select null/0 from dual;

NULL/0

----------

SQL>select 1/0 from dual;

select1/0 from dual

*

ERROR atline 1:

ORA-01476:divisor is equal to zero

取模

SQL>select '*'||mod(9,null)||'*' res fromdual;

RE

--

**

从NULL/0没有报错的情况,我们可以推测出,Oracle发现算术表达式中有null时,并没有真正地计算该表达式,而是直接返回了null。

SQL>select 1 from dual where null!=null;

no rowsselected

SQL>select 1 from dual where null = null;

no rowsselected

SQL>select 1 from dual;

1

----------

1

不管是null!=null 还是null=null计算的结果都为false(实际上是返回了null, null在逻辑中表现为false),可见,不管是算术运算还是逻辑运算,只要null参与,结果就是null

1.1.2 null值与字符串连接

null与字符型字段连接时,表现为什么都没有"",相当于零个字符

SQL>select '*'||null||'*' from dual;

'*

--

**

注意: 如果在实验时出现中文乱码,请确认数据库服务nls_database_parameters,服务器echo $NLS_LANG/ set NLS_LANG,以及客户端v$nls_parameters的编码设置是否一致。

1.1.3 null的查询方式

SQL> select * from emp where comm is null;

其他的查询方式会先过滤过列的null值所在行的记录,即null不参与is null /is not null之外的查询

?

SQL>select count(*) from emp;

COUNT(*)

----------

14

SQL>select count(*) from emp where comm<=500;

COUNT(*)

----------

3

SQL>select count(*) from emp where comm>500;

COUNT(*)

----------

1

?

1.1.4 null所在列的排序

在order by 排序中,null值最大

SQL>select ename, comm from emp order by comm;

?

TURNER 0

ALLEN 300

WARD 500

MARTIN 1400

SCOTT

KING

ADAMS

JAMES

FORD

MILLER

BLAKE

JONES

SMITH

?

CLARK

14 rowsselected.

1.1.5 is null不走索引

在SQL的优化中有时会遇到SQL语句有索引也应该走索引,但最终却没有走索引的情况,这里的is null就是其中的一种情况。

create table n1(sid integer,sname varchar2(120));

插入1W条记录,第1W条的sname值为null

begin

for i in 1..9999 loop

insert into n1 values(i,'name'||i);

if mod(i,100)=0 then

commit;

end if;

end loop;

insert into n1(sid) values(10000);

commit;

end;

查询sname列值走的是索引范围扫描

?

SQL> explain plan for select * from n1 where sname = 'name1';
Explained.

SQL> select * from table(dbms_xplan.display);
Plan hash value: 3644017351
--------------------------------------------------------------------------------
| Id  | Operation	 | Name 	| Rows	| Bytes | Cost (%CPU)| Time
|
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |		|     1 |    75 |     2   (0)| 00:00:01
|
|*  1 |  INDEX RANGE SCAN| N1_SNAME_IND |     1 |    75 |     2   (0)| 00:00:01
|
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("SNAME"='name1')
Note
-----
   - dynamic sampling used for this statement (level=2)

?

is null方式查询,虽然sname中为null的记录1W行中只有一行,但还是没有走索引,也就是说is null不走索引。

SQL> explain plan for select * from n1 where sname is null;
Explained.

SQL> select * from table(dbms_xplan.display);
Plan hash value: 2416923229
--------------------------------------------------------------------------
| Id  | Operation	  | Name | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |	 |     1 |    75 |     9   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| N1	 |     1 |    75 |     9   (0)| 00:00:01 |
--------------------------------------------------------------------------
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇java.sql.SQLException:索引中丢.. 下一篇sql多表连接查询

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: