数据库解析

1.知识点:not in/not exists+null

准备:

关于where条件:
X AND Y: 只要X或者Y有一个是FALSE或者null的话,X AND Y返回FALSE。

关于null:
一个NULL值意味着未知,因此,对一个NULL值的任何比较或操作也都是无效的,而任何返回NULL的测试也都被忽视了。
所以:
select 'true' from dual where 1 = null;
select 'true' from dual where 1 != null;
select 'true' from dual where 1 is null;
以上比较不返回任何值。

select 'true' from dual where null is null;
null is null不是比较,而是说null 是个null,所以返回一行。

~~~~~~~~~~~~~~~~
IN:
This comparison operator tests set membership. It means "equal to any member of." The set can contain nulls, but they are ignored.
Also, expressions of the form value NOT IN set yield FALSE if the set contains a null.

in后里面的列表可以包括null,但是因为相当于用=依次比较,然后去or,true or null =true,所以他们是被忽视的(不理睬)。
SQL> select count(*) from usergrade where username in (select username from usertable);

  COUNT(*)
----------
         1

not in实际上是用!=依次比较列表,然后去and,TRUE AND NULL = NULL。只要列表包括null值,就会返回FALSE(此where条件为FALSE)。
所以,当not in后面是子查询时, 只有保证select后面的字段有not null约束或暗示的时候才能使用。
SQL> select count(*) from usergrade where username not in (select username from usertable);

  COUNT(*)
----------
         0
为了防止这种情况发生,可以在列表中阻止返回null:
not in (select a from t where a is not null);
not in (select nvl(a,0) from t);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EXISTS:
EXISTS(n) returns TRUE if the nth element in a collection exists.
也就是说exists考虑的是(n)返回的行数,而不是值。
SQL> select count(*) from usergrade g where not exists
  2   (select null from usertable t where t.userid=g.userid and t.username=g.username);

  COUNT(*)
----------
         3


2.知识点:in/exists+rownum

Select count(*) from usertable t1 where exists
   (select 'x' from usergrade t2 where t1.username=t2.username and rownum <=1);

rownum <=1在这里作用不大,只要不是rownum<=0即可(子查询返回0行)。后者使得exists(n)一定返回FALSE。


3.知识点:封锁与并发
问题一:只关心session2的变化,因为session1还没有提交,不用理睬;
问题二:查询emp的结果。这个表在T1和T2分别由两个session修改了不同的行,都已经提交,所以看最后结果就好了。
问题三:T4的时候,发生了dept表上的行锁等待。
T5 session2提交,释放锁。使得session1的事务继续。session1 的update操作根据本事务的可视数据(不理睬session2的修改,事务的一致性)修改数据,并提交。
所以,dept表的数据由后来提交的session1决定。



4.知识点:关联更新
答案返回null。
应该改成:
Update student_grade s set s.grade =
(select t.grade from student_makeup t where s.id=t.id)
Where Exists ( Select 1 From student_makeup t Where s.id=t.id)

或者:
Update student_grade s set s.grade =
(select t.grade from student_makeup t where s.id=t.id)
where s.grade<60


5.知识点:DDL与封锁
返回800

DDL可以看成3个步骤:
先commit;
然后ddl语句;
然后commit;

这个实验可以这样理解:
T3的操作因为修改了与T2修改的相同的行,会产生行锁等待。
T4可以理解成上面说的ddl的3个步骤:
先commit,提交T2的delete 100rows,释放锁;
T3操作得到锁,进行delete,并逐个commit;
这个过程,同时也进行truncate,但是由于锁的存在,报错:
ERROR 位于第 1 行:
ORA-00054: 资源正忙,要求指定 NOWAIT

此时,session2的操作也完成了删除100rows,并且都提交。所以一共删除了200行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值