--每页10行,查询第2页,按成绩排序降序
--两种方式:1、top 2、row_number()
--1、top方式:
select top(10) * from student where 成绩 not in
(select top(10*(2-1)) 成绩 from student order by 成绩 desc) as t
order by 成绩 desc
;
--2、row_number()方式:思路:1、先在后面加一列序号 2、把加完序号的虚表作为原表,查询指定范围
select * from
(select *,序号=ROW_NUMBER() over(order by id) from student)as t
where t.序号 between 10*(2-1)+1 and 10*2;
;
--mysql实现:
select * from student limit 10*(2-1)+1,10;
--咱们以后用的是mysql和oracle,绝对不用sqlserver select * from
------------------------局部变量--------------------------------
--java中怎么声明变量 int a; private int a; public static int a; a = 10;
declare @a int;
set @a=10;
select @a;
use wx105;
declare @name nvarchar(50);
select top(1) @name=name from stuInfo_new where id=1;
select @name='赵云';
set @name='赵云';
select @name;
--总结:声明变量只有一种方式:declare 给变量赋值有三种:1、set 2、select 3、select查询后的结果赋值
declare @name nvarchar(50);
declare @gexing nvarchar(100);
set @name='刘书靖';
select @gexing='窈窕淑女!哈哈哈!!!';
select @name as 姓名,@gexing as 个性;
--java中一次声明多个变量:int a,b,c,d,e sql中也可以
declare @name nvarchar(100), @gexing nchar(50); --一次性声明多个变量
set @name='刘书靖';
select @gexing='窈窕淑女!哈哈哈!!!';
--select @name as 姓名,@gexing as 个性;
print @name;--print不能一次性打印多个变量
-----------------------循环(while)----------------------
declare @a int
set @a = 10
while (@a<20) begin
print @a
set @a+=1
end
--计算1到100之间所有整数之和
declare @i int = 1
declare @sum int = 0
while(@i<=100)begin
set @sum=@sum+@i
set @i = @i + 1
end
select @sum
--java中的if else
--输出100以内所有的奇数
declare @i int = 1;
while(@i<=100)begin
if(@i%2!=0)begin
print @i;
end
set @i = @i+1;
end
--需求:当i是10的时候,输出“刘淑静是个大美女”,然后结束本循环
declare @i int = 1
while(@i<=100)begin
print @i
if(@i=10)begin
print '刘淑静是个大美女'
break
end
print @i
set @i = @i + 1
end
--需求:当i是10的时候,输出“高帅是个大美男”,然后结束本次循环,继续下次循环
declare @i int = 0;
while(@i<=100)begin
set @i = @i + 1
select @i
if(@i=10)begin
select '高帅是个大美男'
continue
end
select @i
end
--1到100之间所有偶数之和
declare @i int = 1,@sum int = 0
while(@i<=100)begin
if(@i%2 <> 0)begin -- <>和!=一样,而java中的==在sql中没有,只有=
set @sum = @sum + @i
end
set @i = @i+1
end
print @sum
--sql中没有for循环
--全局变量,由系统维护,我们只能查询,不能修改。但是我们可以自己创建
print @@version;(SQLserver的版本信息)
set @@VERSION='哈哈哈';
declare @@a int =10
set @@a = 100
print @@a
print @@error(最后一个T-SQL错误的错误号)
select * from stuInfo_new group by name;
update accout set 余额=余额-1000000 where name='将冲';
update accout set 余额=余额+1000000 where name='赵与';
print @@error
print @@identity(最后一次插入的标识值)
print @@language(当前使用的语言名称)
print @@max_connections(可以创建的同时连接最大的数目)
select * from stuInfo_new
print @@rowcount(受到上一个SQL语句影响的行数)
create table account
(
id int primary key identity(1,1),
name nvarchar(100) not null,
money bigint not null check(money>=10) default(10)
)
insert into account values('蒋冲',100)
insert into account values('赵云',90)
select * from account
二个选一个写即可
①
begin transaction --开启一个事务
declare @e int = 0
update account set money = money- 90 where name like '赵云'
set @e += @@error --有个特点,读取一次之后,重置为0
update account set money = money+ 90 where name like '蒋冲'
set @e += @@error
if(@e<>0)begin --@e不等于0,说明出过错
rollback --回滚
end else begin
commit --提交
end
--需求:把上面代码再写一遍
②
begin transaction --开启一个事务 在这里,可以把transaction简写成tran,但是不能省略
declare @sum int = 0
update account set money = money-90 where name like '赵云'
set @sum += @@ERROR --记录错误信息
update account set money = money+90 where name like '蒋冲'
set @sum += @@ERROR
if(@sum<>0)begin --判断是否出过错
rollback transaction --在这里,transaction可以简写成tran,也可以省略掉不写
end else begin
commit transaction --在这里,transaction可以简写成tran,也可以省略掉不写
end
--默认隐式事务未开启
update account set money = money-90 where name like '赵云'
update account set money = money+90 where name like '蒋冲'
select * from account
--
set implicit_transactions on --开启隐式事务,开启后,必须手动提交或者回滚
--蒋冲的操作
update account set money = money-10 where name like '赵云'
update account set money = money+10 where name like '蒋冲'
--刘振兴的操作
update account set money = money-1000 where name like '蒋冲'
--马晓雨的操作
update account set money = money+1000 where name like '赵云'
rollback
(重在理解)最好用自己的话记。
--------------------脏读、不可重复读、幻读(虚读)----------------------
--脏读:即读取到不正确的数据,因为另一个事务可能还没提交最终数据,这个读的事务就读取了中途的数据,这个数据可能是不正确的。 解决办法就是后面要讲的设置事务的隔离级别为“Read committed(读已提交) ”。
--不可重复读:即在一次事务之间,进行了两次读取,但是结果不一样,可能第一次id为1的人叫“李三”,第二次读id为1的人就叫了“李四”。原因是因为读取操作不会阻止其他事务。 解决办法就是后面要讲的设置事务的隔离级别为“Repeatable read(可重复读) ”。
--幻读:可重复读阻止的写事务包括update和delete(只给存在的表加上了锁),但是不包括insert(新行不存在,所以没有办法加锁),所以一个事务第一次读取可能读取到了10条记录,但是第二次可能读取到11条,这就是幻读。 解决办法就是后面要讲的设置事务的隔离级别为“Serializable(串行化) ”。
--总结:这三个的区别:脏读是读取到了对方没有提交的数据,原因是这边的读取操作无法控制别人的事务操作。通俗点说就是帅兵转10000给赵云,还没提交,赵云就查看了,发现已经到账了,但是之后帅兵又回滚了,那刚才赵云读到的数据就是脏的
--不可重复读是两次读取数据不一样,原因是无法阻止别的事务的所有操作(增、删、改、查),通俗点说就是蒋冲在ATM机上查询余额的时候,不能阻止他媳妇的任何操作
--幻读是两次读取的表的行数不一样,原因是即使设置了可重复读,也无法阻止别人的插入操作,通俗点说就是第一次查看咱班的表行数是46,然后别人进咱班了,我又查看了一次,发现变成47人了,这种情况就是幻读
--以上这几个问题需要解决:隔离
--隔离有四种,分别解决以上三个问题:
--1、read commited(读已提交):解决了脏读问题,就是说只要设置数据库的隔离级别为这个级别,就不会出现脏读情况了。原理:当表被更新但没提交或回滚时,此表处于隔离状态,其他用户(会话)无法查询
-- 演示脏读现象:数据库默认级别是read commited级别,已经不会出现脏读现象了,所以我们为了演示,把级别降低为
DBCC USEROPTIONS
set transaction isolation level read uncommitted --设置本会话的隔离级别为最低级别
select * from account
set transaction isolation level read committed --设置本会话的隔离级别为最低级别
select * from account
update account set money=1000 where name like '赵云';
--2、repeatable read(可以重复读):解决了不可重复读的问题,就是说只要设置数据库的隔离级别为这个级别,就不会出现不可重复读的情况了
--演示不可重复读现象:
set implicit_transactions on --手动设置事务
select * from account where name like '蒋冲';
commit
set transaction isolation level repeatable read
set implicit_transactions on
select * from account where name like '蒋冲';
select * from account where name like '蒋冲';
commit
--3、serializable(串行化):解决了幻读的问题,就是说只要设置数据库的隔离级别为这个级别,就不会出现幻读的情况了
--演示幻读现象:
select * from account
commit
select * from account
delete from account where name like '马晓雨';
commit
--解决方案:设置隔离级别为serializable
set transaction isolation level serializable
select * from account
commit
select * from account
--总结:read uncommitted < read committed < repeatable read < serializable 这几个级别越来越高,高的级别可以把前面所有的问题都解决掉,注意:越往后效率越低