T-SQL语句:建库,建表,建约束,简单编程, 各种查询,事务,视图,索引,存储过程···


use master
go

--允许数据中的调用DOS命令
exec sp_configure 'show advanced options' , 1
go
reconfigure
go 
exec sp_configure 'xp_cmdshell',1
go 
reconfigure
go


--数据中中调用dos命令
exec xp_cmdshell 'mkdir F:\数据库'    --xp_cmdshell自带存储过程    --- mkdir:DOS 创建文件夹命令
exec xp_cmdshell 'dir d:'

exec sp_configure 'xp_cmdshell' , 0
go
reconfigure
go
exec sp_configure 'show advanced options' , 0
go
reconfigure
go

use master

if exists(select * from sysdatabases where name='MySchool' )   --exists验证是否存在数据库   数据库存在于啥意思database中
begin
drop database MySchool      ---删除数据库
end

create database MySchool   ---创建数据库
on primary                 ---编写数据库mdf文件相关属性
(
	name='MySchool_data',  ---数据库名称
	filename = 'F:\数据库\MySchool_data.mdf', ---数据库物理路径
	size=5MB,                                 ---数据库初始大小
	maxsize=10MB,                             ---数据库最大大小
	filegrowth=15%                            ---数据库增量
)
log on                      ---编写数据库日志文件
(
	name='MySchool_Log',    ---日子文件名称
	filename='F:\数据库\MySchool_Log.ldf',  ---日志文件物理路径
	size=5MB,                               ---日志文件初始大小
	maxsize=10MB,                           ---日志文件最大大小
	filegrowth=1MB                          ---日子文件增量
)

go



---------创建Subject表
use MySchool
go
if exists(select * from sysobjects where name = 'Subject')
drop table [Subject]
create table [Subject]
(
	SubjectNo int not null identity(1,1),
	SubjectName nvarchar(50) ,
	ClassHour int, 
	GradeID int 
)
go
----------创建Result表
use Myschool
go
if exists (select * from sysobjects where name = 'Result')
drop table Result
create table Result
(
	StudentNo int not null,
	SubjectNo int not null,
	ExamDate datetime not null,
	StudentResult int not null
)
go
--------创建Student表
use MySchool
go
if exists (select * from sysobjects where name = 'Student')   ---验证MySchool中是否包含Student表  表存在于sysobjects中
begin
drop table Student          ----删除表
end

create table Student        ----创建表
(
	StudentNo int not null ,            ----学号(非空)必填
	LoginPwd nvarchar(20) not null ,   ----密码
	studentName varchar(20) not null,  ----学生姓名, 非空(必填)
	sex bit not null ,                  ----性别, 取值0或1
	GradeId int not null,              ----年纪编号 必填
	Phone nvarchar(50)  null ,         ----联系电环 , 允许为空
	Address nvarchar(50) null,         ----地址,允许为空,
	BornDate datetime not null,        ----生日
	Email nvarchar(30) null,           ----邮箱账号
	IdentityCard varchar(18) not null   ----身份证号
)

go
-------创建年纪表
use MySchool
go
if exists(select * from sysobjects where name='Grade')
drop table grade

create table Grade
(
	 GradeID int not null identity(1,1) ,
	 GradeName nvarchar(20) not null 
) 

--***********************************************添加约束
go
----添加主键约束(将GradeID作为主键)
alter table Grade
add constraint PK_GradeID primary key(GradeID)


----添加主键约束(将StudentNo)作为主键
alter table student
add constraint PK_StudentNo primary key(studentno)

----添加唯一约束(身份证号唯一,因为每个人的身份证号全国唯一)
alter table student
add constraint UQ_IdentityCard unique(IdentityCard)

----添加默认约束(如果不填写地址, 则默认为“地址不详”)
alter table student
add constraint DF_Adress default ('地址不详') for address

----添加检查约束(要求出生日期在1980年1月1日后)
alter table student
add constraint CK_BornDate check (borndate >=  '1980-1-1')

----添加外键约束(主表Student和从表Result建立关系 , 关联列为StudentNo)
alter table Result
add constraint FK_StudentNo foreign key (StudentNo) references Student(StudentNo)


----删除Student表中地址列默认约束的语句:
alter table student
drop constraint DF_Adress


----为subject 表添加主键约束
alter table subject
add constraint PK_SubjectNo primary key (SubjectNo)

----为Subject表中的SubjectName 添加非空约束
alter table subject
add constraint CK_SubjectName check(SubjectName is not null)

----Subject 表中ClassHour必须大于0
alter table subject
add constraint CK_ClassHour check(CLassHour>0)

----主表Grade 和从表Subject 通过GradeID建立外键关系
alter table subject
add constraint FK_GradeID foreign key (GradeID) references Grade(GradeID)


----为表Result添加约束
----添加主键约束:(学号, 课程编号和日期构成组合主键)
alter table Result
add constraint PK_ZH primary key(studentno , subjectno , ExamDate)

----添加默认约束:日期为系统当前日期
alter table Result
add constraint DF_ExamDate default(GETDATE()) for examdate

----添加检查约束,成绩不大于100且大于0
alter table result
add constraint CK_StudentResult check( StudentResult>0 and studentresult<100  )

----外键约束
alter table result
add constraint FK_StudentNo2 foreign key (StudentNo) references student(StudentNo)


alter table result
add constraint FK_SubjectNo foreign key (SubjectNo) references [subject](Subjectno)


SELECT * FROM sys.all_objects where name = 'UQ_IdentityCard'    ----验证某个约束是否存在





--========================================插入数据===================================

--向Grade表插入数据
INSERT INTO Grade VALUES('S1')
INSERT INTO Grade VALUES('S2')
INSERT INTO Grade VALUES('Y2')
--向Subject表插入数据
INSERT INTO Subject VALUES('Winforms',20,1)
INSERT INTO Subject VALUES('Java Logic',16,1)
INSERT INTO Subject VALUES('SQL Base',18,1)
INSERT INTO Subject VALUES('HTML',32,1)
INSERT INTO Subject VALUES('Proc',38,1)
INSERT INTO Subject VALUES('Project',36,1)
INSERT INTO Subject VALUES('C# OOP',24,2)
INSERT INTO Subject VALUES('Three Tier',28,2)
INSERT INTO Subject VALUES('Java OOP',12,2)
INSERT INTO Subject VALUES('JSP',26,2)
INSERT INTO Subject VALUES('JavaScript',24,2)
INSERT INTO Subject VALUES('T-SQL',22,2)
INSERT INTO Subject VALUES('Project',42,2)
INSERT INTO Subject VALUES('ASP.NET',38,3)
INSERT INTO Subject VALUES('Control+Ajax',12,3)
--向Student表插入数据
INSERT INTO Student VALUES('10000','GuoJing','郭靖',1,1,02088762106,'天津市河西区','1987-09-08 00:00:00','[email protected]',111111)
INSERT INTO Student VALUES('10001','LiWenCai','李文才',1,1,01062768866,'地址不详','1993-03-04 00:00:00','[email protected]',111112)
INSERT INTO Student VALUES('10002','LiSiWen','李斯文',1,1,02183410615,'河南洛阳','1992-08-08 00:00:00','[email protected]',111113)
INSERT INTO Student VALUES('10011','WuSong','武松',0,1,01062768888,'地址不详','1984-12-31 00:00:00','[email protected]',111114)
INSERT INTO Student VALUES('10012','HeQiang','何强',0,1,02183567890,'地址不详','1991-08-30 00:00:00','[email protected]',111120)
INSERT INTO Student VALUES('20011','ZhangSan','张三',1,1,15290234178,'北京市海淀区','1994-01-01 00:00:00','[email protected]',111115)
INSERT INTO Student VALUES('20012','ZhangQiuYu','张秋丽',0,2,01062751414,'北京市东城区','1990-06-05 00:00:00','[email protected]',111116)
INSERT INTO Student VALUES('20015','XiaoMei','肖梅',0,2,031466557171,'河北省石家庄市','1996-10-01 00:00:00','[email protected]',111117)
INSERT INTO Student VALUES('30021','OuYangJunXiong','欧阳俊雄',1,2,02277585000,'上海市卢湾区','1995-09-29 00:00:00','[email protected]',111118)
INSERT INTO Student VALUES('30023','MeiChaoFeng','梅超风',0,2,031466557172,'广州市天河区','1997-08-30 00:00:00','[email protected]',111119)
----向Result表插入数据
INSERT INTO Result VALUES('10001',2,'2013-02-15 00:00:00',70)
INSERT INTO Result VALUES('10000',2,'2013-02-17 00:00:00',80)
INSERT INTO Result VALUES('10001',2,'2013-02-17 00:00:00',90)
INSERT INTO Result VALUES('10002',2,'2013-02-17 00:00:00',60)
INSERT INTO Result VALUES('10011',2,'2013-02-16 00:00:00',75)
INSERT INTO Result VALUES('10011',2,'2013-02-17 00:00:00',45)
INSERT INTO Result VALUES('10012',2,'2013-02-15 00:00:00',89)
INSERT INTO Result VALUES('20011',2,'2013-02-15 00:00:00',25)
INSERT INTO Result VALUES('20012',2,'2013-02-15 00:00:00',86)
INSERT INTO Result VALUES('20012',7,'2013-02-15 00:00:00',98)
INSERT INTO Result VALUES('20015',2,'2013-02-15 00:00:00',34)
INSERT INTO Result VALUES('20015',7,'2013-02-15 00:00:00',76)
INSERT INTO Result VALUES('30021',2,'2013-02-15 00:00:00',87)
INSERT INTO Result VALUES('30021',8,'2013-02-15 00:00:00',74)
INSERT INTO Result VALUES('30023',2,'2013-02-15 00:00:00',39)
INSERT INTO Result VALUES('30023',9,'2013-02-15 00:00:00',88)


---???????????????查找李文才的信息及与李文才的学号相邻的学生信息?????????????????????????????

/*查找李文才的信息*/
declare @name varchar(10)   --定义变量
set @name='李文才'          --为变量赋值
select studentNo , studentName , BornDate , Address 
from Student
where studentName = @name
/*查找与李文才学号相邻的学生信息*/

declare @studentno int , @name2 varchar(50)
set @name2 = '李文才'
select @studentno = StudentNo from Student    --获取结果并为变量赋值
where studentName = @name2

select * from Student where StudentNo = (@studentno+1) or StudentNo = (@studentno-1)



/*====SET和SELECT语法的区别
----------------------------------------------------------------------------------------------------
							set						select
同时对多个变量赋值			不支持					支持
表达式返回多个值时			出错					将返回的最后一个值赋给变量
表达式未返回值时			变量被赋值为null		变量保持原值
--------------------------------------------------------------------------------------------------*/

print '服务器名称是:'+@@servername

print '服务器版本是:'+@@version

select @@SERVERNAME as '服务器名称'
select @@VERSION as '服务器版本'


----   print '错误类型是:'+@@error   ----错误写法,因为@@error返回的是整型数据,不能用+和字符串数据相连

print '错误类型是:'+ CONVERT(varchar(50) , @@ERROR)


insert into student(studentname , StudentNo , loginpwd , gradeid , sex , BornDate , IdentityCard)
values ('武松',10011,'123456',1,0,'1990-12-31','11010119901231001x')
print '当前错误号为:'+convert(varchar(50) , @@error)
go

update Student set borndate = '1970-7-8' where StudentNo = 10011
print '当前错误为:'+convert(varchar(40) , @@error)

go


select stu.studentName , r.StudentResult   from Student stu
inner join Result r on r.StudentNo = stu.StudentNo
inner join Subject s on s.SubjectNo = r.SubjectNo
where stu.StudentNo ='10000' and s.SubjectName='Java Logic' and r.ExamDate = '2013-02-17'

-----------------------------------------------------------------------------------------------

declare @name3 varchar(20) , @result int , @no int
set @no = 10000

select @name3 = studentName from Student where StudentNo = @no

select @result = r.StudentResult    from Student stu
inner join Result r on r.StudentNo = stu.StudentNo
inner join Subject s on s.SubjectNo = r.SubjectNo
where stu.StudentNo ='10000' and s.SubjectName='Java Logic' and r.ExamDate = '2013-02-17'

print '姓名是:'+ @name3
print '成绩是:'+cast(@result as varchar(20))


declare @BornDate datetime
select @BornDate = BornDate from Student where StudentNo = 10000
print convert(varchar , @BornDate , 120 )
------------------------------------------------------------------ 



------练习一 :打印图形
declare @f varchar(10)
set @f='★'
print @f
print @f+@f
print @f+@f+@f
print @f+@f+@f+@f

------练习二:查询学号是20011的学生姓名和年龄 ,并输出比他大1岁和小1岁的学生信息

use MySchool
go

declare @xuehao int , @age int  , @name4 varchar(23)
set @xuehao=20011
select @name4=studentName , @age = FLOOR(DATEDIFF(DY ,BornDate , GETDATE())/365) from Student where StudentNo = @xuehao
print '学号为20011的姓名是:'+@name4+'  年龄是:'+convert(varchar(10),@age)

select * from student where FLOOR(DATEDIFF(DY ,BornDate , GETDATE())/365)=@age+1 or FLOOR(DATEDIFF(DY ,BornDate , GETDATE())/365) = @age-1



------示例5 
/*
思路:	1、查询Java Logic 最近一次考试的日期
		2、统计平局成绩并存入局部变量
		3、用IF-ELSE语句判断
*/
---------1、查询Java Logic 最近一次考试的日期
declare @time datetime
select @time =MAX(ExamDate) from Result r
inner join Subject s on s.SubjectNo = r.SubjectNo
where s.SubjectName = 'Java Logic'

print '最近的一次Java Logic考试时间为:'+convert(varchar(20) ,@time , 120)
---------2、统计平局成绩并存入局部变量

declare @avg decimal(5,2)
select @avg = AVG(StudentResult) from Result r
inner join Subject s on s.SubjectNo = r.SubjectNo
where s.SubjectName='Java Logic' and r.ExamDate = @time

print '平均分是:'+convert(varchar(20) , @avg)

---------3、用IF-ELSE语句判断
if(@avg>70)
begin
	select top 3 StudentNo , StudentResult from Result r
	inner join Subject s on s.SubjectNo = r.SubjectNo
	where s.SubjectName='Java Logic' and r.ExamDate = @time
	order by r.StudentResult desc
end
else
begin
	select top 3 StudentNo , StudentResult from Result r
	inner join Subject s on s.SubjectNo = r.SubjectNo
	where s.SubjectName='Java Logic' and r.ExamDate = @time
	order by r.StudentResult 
end

go

----------检查winform课程最近一次考试是否有不及格的,如果有不及格的,则每人加2分, 高于95分的则不再加分,直至所有学生此次考试成绩及格为止

declare @time datetime , @subjectNo int , @count int
select @subjectNo = SubjectNo from Subject where SubjectName='Java Logic'

select @time = MAX(ExamDate) from Result where SubjectNo = @subjectNo

while(1=1)
begin
	select @count = count(0) from Result
	where SubjectNo = @subjectNo and ExamDate = @time and StudentResult <60
	if(@count>0)
	begin
		update Result set StudentResult = StudentResult+2 
		where SubjectNo = @subjectNo and ExamDate = @time and StudentResult <95
	end
	else
	begin
		break
	end
end 

select s.studentName ,r.StudentResult  from Student s
inner join Result r on r.StudentNo = s.StudentNo
where r.SubjectNo = @subjectNo and r.ExamDate = @time

go



-------采用A~E五级打分制来显示学生“Java Logic”课程最近一次的考试成绩
declare @ExamTime datetime
select @ExamTime = MAX(ExamDate) from Result r
inner join Subject s on r.SubjectNo = s.SubjectNo
where s.SubjectName = 'Java Logic'

select 学号=StudentNo , 成绩=
case
	when StudentResult<60 then 'E'
	when StudentResult between 60 and 70 then 'D'
	when StudentResult between 70 and 80  then 'C'
	when StudentResult between 80 and 90  then 'B'
	when StudentResult between 90 and 100 then 'A'
end
from Result r
inner join Subject s on r.SubjectNo = s.SubjectNo
where s.SubjectName = 'Java Logic' and r.ExamDate = @ExamTime



/*查询学号是20012的学生的Java Logic课程最近一次考试的成绩
 并输出学生姓名和考试对应等级信息,如果大于85分,则显示‘优秀’ , 如果大于70则显示‘良好’如果大约60则显示‘中等’否则显示‘差’
 */
 use MySchool
 declare @subNo int  , @MaxTime datetime , @StuName varchar(10)
 select @subNo = SubjectNo from Subject where SubjectName='Java Logic'
 select @MaxTime =MAX(ExamDate) from Result where  SubjectNo = @subNo and StudentNo = 20012
 select @StuName = studentName from Student where StudentNo = 20012

 select 姓名 = @StuName ,成绩 = 
 case
	when StudentResult >85 then '优秀'
	when StudentResult >70 then '良好'
	when StudentResult >60 then '中等'
	else '差'
 end 
 from Result where SubjectNo = @subNo and StudentNo = 20012 and ExamDate = @MaxTime



 /*批处理
	为了督促学生学习, 学校对多次考试不及格的学生给予处理:凡是一次考试不及格者, 给予警告;3次含以下不及格者,按肄业处理;3次以上不及格者,开除学籍
	(1)创建临时表Punish , 表结构如下。
		处罚记录(学号、不及格次数、处理意见)
		创建新表时处理意见为空
	(2)查询所有不及格的成绩并插入Punish表
	(3)根据每个学生不及格次数批量更新处理意见	
 */
 --批处理1
 if exists (select * from sysobjects where name = 'Punish')
 drop table punish
 create table Punish
 (
	StuNo int not null,
	StuCnt int not null,
	StuMng varchar(50)
 )
 go
 --批处理2
 insert into Punish
	select StudentNo 学号 , COUNT(0) 不及格次数, '' 处理意见 from Result where StudentResult<60
	group by StudentNo
go
update Punish set StuMng='警告' where StuCnt=1

update Punish set StuMng='肄业' where StuCnt=2 and StuCnt = 3 
update Punish set StuMng='开出' where StuCnt>3 
go

select * from Punish
go

/**创建Admin表, 插入两个管理员记录, 变更第一个管理员密码*/
if exists (select * from sysobjects where name='admin')
drop table admin
create table admin
(
	Name varchar(20) not null,
	Pwd varchar(10) not null
)

go

alter table admin
add constraint PK_Name primary key (Name)

go

insert into admin values('毛新建','11111')
insert into admin values('猴哥' ,'fdsfds')

go

update admin set pwd='22222' where Name='毛新建'
go


/*查询年龄比‘李斯文’小的学生 , 要求显示这些学生的信息
思路找到李斯文的出生日期,找到比李斯文出生日期大的学生
*/
----方法一:
declare @BornDateL datetime
select @BornDateL = BornDate from Student where studentName = '李斯文'
select * from Student where BornDate > @BornDateL

---方法二:
select * from Student where BornDate > 
(select BornDate from Student where studentName = '李斯文')

/*子查询语法:select ..... from 表1 where 列1 >( 子查询  )

注意:讲子查询和比较运算符联合使用, 必须保证子查询返回的值不能多于一个
*/


update Result set StudentResult = 60 where StudentNo='10002'


/**查询Java Logic 课程至少一次考试成绩刚好等于60 分的学生名单*/
 
 select s.studentName , r.StudentResult from Student s
inner join Result r on r.StudentNo = s.StudentNo
inner join Subject sub on sub.SubjectNo = r.SubjectNo
where sub.SubjectName='Java Logic' and r.StudentResult=60  

select studentName from Student where StudentNo  = ( 
	select StudentNo from Result r inner join Subject s on s.SubjectNo = r.SubjectNo
	where r.StudentResult=60 and s.SubjectName='Java Logic'
 )


 /**查询参加最近一次C#OOP考试成绩的学生的最高分和最低分**/

 ---方式1
declare @ExamDateC datetime , @SubNo int
select @SubNo = SubjectNo  from Subject where SubjectName = 'Java Logic'
select @ExamDateC = MAX(ExamDate) from Result where SubjectNo = @SubNo

select MAX(studentresult) 最大分 , MIN(studentresult) 最小分 from Result  where ExamDate = @ExamDateC and SubjectNo = @SubNo

---方式2
select MAX(studentresult) 最大分 , MIN(studentresult) 最小分 from Result 
where ExamDate = ( select MAX( ExamDate) from Result where SubjectNo = ( select SubjectNo from Subject where SubjectName='Java Logic' ) ) 

/**查询Java Logic 课程至少一次考试成绩刚好等于大于60 分的学生名单*/
---方式1
 select s.studentName , r.StudentResult from Student s
inner join Result r on r.StudentNo = s.StudentNo
inner join Subject sub on sub.SubjectNo = r.SubjectNo
where sub.SubjectName='Java Logic' and r.StudentResult>60  
---方式2
select studentName from Student where StudentNo  in ( 
	select StudentNo from Result r inner join Subject s on s.SubjectNo = r.SubjectNo
	where r.StudentResult>60 and s.SubjectName='Java Logic'
 )
 ---方式3
 select studentname from student where StudentNo in (
	select StudentNo from Result  where StudentResult >=60 and  subjectno =  (select SubjectNo from Subject where SubjectName='Java Logic')
 )


 /**查询参加Java Logic 课程最近一次考试的在读学生名单**/

 ----方式1
 declare @SubjectNo int , @ExamDateMax datetime   ---定义课程编号和最近一次考试日期
 select @SubjectNo =  SubjectNo from Subject where SubjectName = 'Java Logic'     ---获取课程编号
 select @ExamDateMax = MAX(ExamDate) from Result where SubjectNo = @SubjectNo     ---获取该课程编号最近一次考试的日期
 select studentName from Student  s inner join Result r on s.StudentNo = r.StudentNo     ----获取参加该课程最后一次考试的人员姓名
 where r.SubjectNo = @SubjectNo and ExamDate = @ExamDateMax


 ----方式2

 select StudentName from Student 
	where StudentNo in (
			select StudentNo from Result 
			where SubjectNo = (select SubjectNo from Subject where SubjectName='Java Logic')
			and ExamDate = (select MAX(ExamDate) from Result where  SubjectNo = (select SubjectNo from Subject where SubjectName='Java Logic'))
 )


 /**查询没有参加Java Logic考试的在读学生名单**/
  select StudentName from Student 
	where StudentNo not in (
			select StudentNo from Result 
			where SubjectNo = (select SubjectNo from Subject where SubjectName='Java Logic')
			and ExamDate = (select MAX(ExamDate) from Result where  SubjectNo = (select SubjectNo from Subject where SubjectName='Java Logic'))
 ) and GradeId = ( select GradeId from Subject where SubjectName = 'Java Logic' )


 /**查询某学期开设的课程(假定查询S1学期开设的课程)**/
 select SubjectName from Subject where GradeID = (select  GradeID from Grade where GradeName= 'S1' )


 /**查询某课程最近一次考试缺考的学生名单**/

 select studentname from Student where StudentNo not in (
	select StudentNo from Result 
	where ExamDate = (
		select MAX(ExamDate) from Result 
		where SubjectNo = (
			select SubjectNo from Subject where SubjectName = 'SQL Base') )
	and SubjectNo = (  select SubjectNo from Subject where SubjectName = 'SQL Base' )
 ) and GradeId = ( select GradeID  from Subject where SubjectName = 'SQL Base' )


 /**检查Java Logic 课程最近一次成绩。如果有成绩达到80分以上者 , 则每人加2分 , 否则每人加5分; 最终的成绩不得大于100分**/

 if exists(
	 select * from Result where
	 SubjectNo =  (select SubjectNo from Subject where SubjectName='Java Logic') 
	 and ExamDate = ( select MAX(ExamDate)  from Result where SubjectNo =  (select SubjectNo from Subject where SubjectName='Java Logic')  ) 
	 and StudentResult>80
 )
 begin
	update Result set StudentResult = StudentResult+2 where 
	SubjectNo = (select SubjectNo from Subject where SubjectName='Java Logic') 
	and ExamDate = ( select MAX(ExamDate)  from Result where SubjectNo =  (select SubjectNo from Subject where SubjectName='Java Logic')  ) 
	and StudentResult<99
 end
 else
 begin
	update Result set StudentResult = StudentResult+5 where 
	SubjectNo = (select SubjectNo from Subject where SubjectName='Java Logic') 
	and ExamDate = ( select MAX(ExamDate)  from Result where SubjectNo =  (select SubjectNo from Subject where SubjectName='Java Logic')  ) 
	and StudentResult<96
 end



 /**检查Java Logic 课程最近一次考试,如果全部没有通过考试(60分及格), 则试题偏南,每人加3分;否则,每人加1分  (最高分不超过97) **/

  if not exists(
	 select * from Result where
	 SubjectNo =  (select SubjectNo from Subject where SubjectName='Java Logic') 
	 and ExamDate = ( select MAX(ExamDate)  from Result where SubjectNo =  (select SubjectNo from Subject where SubjectName='Java Logic')  ) 
	 and StudentResult>=60
 )
 begin
	update Result set StudentResult = StudentResult+3 where 
	SubjectNo = (select SubjectNo from Subject where SubjectName='Java Logic') 
	and ExamDate = ( select MAX(ExamDate)  from Result where SubjectNo =  (select SubjectNo from Subject where SubjectName='Java Logic')  ) 
	and StudentResult<96
 end
 else
 begin
	update Result set StudentResult = StudentResult+1 where 
	SubjectNo = (select SubjectNo from Subject where SubjectName='Java Logic') 
	and ExamDate = ( select MAX(ExamDate)  from Result where SubjectNo =  (select SubjectNo from Subject where SubjectName='Java Logic')  ) 
	and StudentResult<97
 end





/*************************************************************第六章:事物、视图、索引*************************************************************************/

use MySchool
go
----创建农行帐户Bank
if exists (select * from sysobjects where name='Bank')
drop table Bank
create table Bank 
(
	CustomerName varchar(10) , ----顾客姓名
	CurrentMoney money         ----当前余额 
)
go

----添加约束
alter table Bank          ------银行余额必须大于1
add constraint CK_CurrentMoney check ( CurrentMoney >= 1  )
go

----插入三个测试记录

insert into Bank values( '张三' ,1000  )
insert into Bank values('李四',1)

----查看结果
select * from Bank
go


----转账测试:张三希望通过转账, 直接汇款给李四1000元
/*
update bank set CurrentMoney = CurrentMoney - 1000 where CustomerName='张三'

update bank set CurrentMoney = CurrentMoney + 1000 where CustomerName='李四'

select * from Bank

*/

-----修改为事务控制的形式
use MySchool
go

set nocount on

print '没有修改前的数据为'
select * from Bank
go

declare @count int 
set  @count = 0

begin transaction

update bank set CurrentMoney = CurrentMoney - 1000 where CustomerName='张三'

set @count = @count +@@ERROR

update bank set CurrentMoney = CurrentMoney + 1000 where CustomerName='李四'

set @count = @count + @@ERROR

print '没有提交事务前'

select * from Bank
----判断是否有错误,有错误回滚,没有错误则提交
if (@count<>0)
begin
	rollback transaction
end
else 
begin
	print '交易成功,提交事务'
	commit transaction
end
go

---查看最后的数据
print '最后的数据是:'
select * from Bank
go


------------插入5条学生Java Logic 成绩
BEGIN TRANSACTION 
DECLARE @errorSum INT
SET @errorSum=0
/*--插入数据--*/
INSERT INTO Result(StudentNo,SubjectNo,ExamDate,StudentResult)
            VALUES(10000,2,GETDATE(),90)
SET @errorSum=@errorSum+@@error
INSERT INTO Result(StudentNo,SubjectNo,ExamDate,StudentResult)
            VALUES(10001,2,GETDATE(),70)
SET @errorSum=@errorSum+@@error
INSERT INTO Result(StudentNo,SubjectNo,ExamDate,StudentResult)
            VALUES(10002,2,GETDATE(),67)
SET @errorSum=@errorSum+@@error
INSERT INTO Result(StudentNo,SubjectNo,ExamDate,StudentResult)
            VALUES(10012,2,GETDATE(),55)
SET @errorSum=@errorSum+@@error
INSERT INTO Result(StudentNo,SubjectNo,ExamDate,StudentResult)
            VALUES(10011,2,GETDATE(),102)--分数违反约束
SET @errorSum=@errorSum+@@error


/*--根据是否有错误,确定事务是提交还是撤销--*/
IF(@errorSum<>0) --如果有错误
  BEGIN
    PRINT '插入失败,回滚事务'
    ROLLBACK TRANSACTION 
  END  
ELSE
  BEGIN
    PRINT '插入成功,提交事务'
    COMMIT TRANSACTION   
  END
GO



/**上机练习2
	相关知识:
	--  <二>、插入多行数据
	--  1、将现有表中的数据添加到已存在的表
		insert into 新表 (字段,字段) select 字段,字段 from 原始表
	--2、将现有表中的数据添加到新表中
		select 原始表.字段1,原始表.字段2 into 新表 from 原始表
	--3、通过UNION关键字合并数据进行插入
		insert 新表(字段1,字段2) select 数据1,数据2 union select 数据3,数据4 union select 数据5,数据6
    --如需创建一个包含标识列的新表,那么在插入数据前就要创建一个新的标识列,因为标识列的数据不允许指定,语法如下:
		select IDENTITY (数据类型,标识种子,标识增长量) as 列名 into 新表 from 原始表
**/

declare @c int
set @c = 0 
----将Y2的学生成绩插入HistoryResult表中
begin transaction
select r.* into HistoryResult from Result r where r.StudentNo in 
( select StudentNo from Student 
	where GradeId = (select GradeId from Grade where GradeName = 'Y2') )
set @c = @c+@@ERROR
----将Y2的学生从成绩表(Result)中删除
delete result where StudentNo in 
( select StudentNo from Student 
	where GradeId = (select GradeId from Grade where GradeName = 'Y2') )
set @c = @c+@@ERROR

select s.* into HistoryStudent from Student s where s.GradeId in 
(select GradeId from Grade where GradeName = 'Y2') 
set @c = @c+@@ERROR
----将Y2的学生从成绩表(Result)中删除
delete Student where StudentNo in 
(select GradeId from Grade where GradeName = 'Y2') 
set @c = @c+@@ERROR

if(@c<>0)
begin
	print '程序有错误终止执行'
	rollback transaction
end
else
begin
	print '程序执行成功'
	commit transaction
end




/**使用视图**/

----示例4: 使用T-SQL语句为教员查看Java Logic课程最近一次考试成绩的视图,并通过视图获得查询结果
use MySchool
go
if exists( select * from sysobjects where name='vw_Result_Java' )
drop view vw_Result_Java 
go

create view Result_Java
as 
select s.studentName as 学生姓名 , s.StudentNo as 学生编号 ,sub.SubjectName as 课程 ,  r.StudentResult as 成绩 from Student s
inner join Result r on r.StudentNo = s.StudentNo 
inner join Subject sub on sub.SubjectNo = r.SubjectNo
where sub.SubjectName = 'Java Logic' and r.ExamDate = 
	(select MAX(ExamDate) from Result where SubjectNo = ( select SubjectNo from Subject where SubjectName = 'Java Logic') )
go

select * from Result_Java
go



/**统计每个学生各学期(S1 , S2, Y2 )所有课程的总成绩 **/



select s.StudentNo as 学号 , s.studentName as 姓名 ,s.Phone as 电话 , gg.GradeName as 年纪 , temp.result as 成绩    from 

(select r.StudentNo as studentno , g.GradeID as gradeid , sum(r.StudentResult) as result from result r 
inner join (select studentNo , subjectno ,   MAX(ExamDate) examdate from Result  group by StudentNo , SubjectNo ) temp2 on r.SubjectNo = temp2.SubjectNo and r.StudentNo = temp2.StudentNo and temp2.examdate = r.ExamDate
inner join Subject sub on sub.SubjectNo = r.SubjectNo
inner join Grade g on g.GradeID = sub.GradeID
group by r.SubjectNo   ,r.StudentNo , g.GradeID ) temp
inner join Student s on s.StudentNo = temp.studentno
inner join Grade gg on gg.GradeID = temp.gradeid


/**创建索引的语法*

create [unique]  [clustered][nonclustered] index index_name
on table_name (column_name , .......)
[with fillfactor=x]

unique 指定唯一索引,可选
clustered 、 noclustered 指定是聚集索引还是非聚集索引 , 可选
fillfactor :表示填充因子,指定0~100的值

*/

/**删除的语法**/

drop index table_name.index_name    ----table_name 表名 ; index_name 索引名

/**检测是否存在该索引(索引存放在系统表  sysindexes  中)**/
use MySchool
go
if exists ( select * from sysindexes where name = 'IX_Student_StudentName' ) ---验证是否有索引 IX_Student_StudentName
drop index student.IX_Student_StudentName									 ---删除索引 

create nonclustered index IX_Student_StudentName							 ---创建索引
on student(studentName)
with fillfactor=30


/**使用索引IX_Student_StudentName**/
select * from Student 
with (index = IX_Student_StudentName)
where studentName like '李%'

/**查看索引**/
--用系统存储过程sp_helpIndex查看
exec sp_helpindex Result

--用视图sys.indexes 查看
use  MySchool
select * from sys.indexes




/*===============================================================第7章===========================================================*/
----常用的系统存储过程的使用
exec sp_databases						---列出当前系统中的数据库
exec sp_renamedb 'MySchool' ,'School'	---改变当前数据的名称(单用户访问)
exec sp_renamedb 'School' ,'MySchool'	---改变当前数据的名称(单用户访问)
use MySchool
go
exec sp_tables							---当前数据库中可查询对象的列表
exec sp_columns student					---获取student 表中列的信息
exec sp_help student					---查看Student表中的所有信息
exec sp_helpconstraint student			---查看Student表中的约束
exec sp_helptext Result_Java			---查看视图的语句文本
exec sp_stored_procedures				---返回当前数据库中存储过程的列表




/**==================创建不带参数的存储过程
	查询Java Logic 课程最近一次考试的平均分,依据平均分对本次考试成绩给出评价
	(平均分高于70分,评价为优秀, 否则评价为 较差  )
	并给出喂通过考试的学员名单
=======================**/
use MySchool
go
if exists ( select * from sysobjects where name = 'usp_GetAvgResult'  )
drop procedure usp_GetAvgResult
go
create proc usp_GetAvgResult
as
declare @maxTime datetime , @SubNo int      --声明最近考试时间, 和科目编号
select @SubNo = SubjectNo from Subject where SubjectName = 'Java Logic' ---获取科目编号
select @maxTime = MAX(ExamDate) from Result where SubjectNo = @SubNo    ---获取最后一次考试时间
declare @avgResult decimal(18,2)										---定义平均分
select @avgResult = AVG(StudentResult) from Result  where SubjectNo = @SubNo and ExamDate =@maxTime       ---获取平均分

print '平均分是:'+convert(varchar(10) , @avgResult)
if(@avgResult >70)
begin
	print '考试成绩:优秀'
end
else
	print '考试成绩:较差'

print '参加本次考试没有通过的学院有:'

select studentName ,Result.StudentNo , StudentResult  from Result 
inner join Student on Result.StudentNo = Student.StudentNo     
where SubjectNo = @SubNo and ExamDate =@maxTime and StudentResult<60

go

exec usp_GetAvgResult

/*利用存储过程查询各学期开设的课程名称和每门课程的课时*/

if exists(select * from sysobjects where name = 'usp_SubjectName')
drop procedure usp_SubjectName
go
create proc usp_SubjectName
as
select GradeName , SubjectName , ClassHour   from Subject 
inner join Grade on Grade.GradeID = Subject.GradeID
go

exec usp_SubjectName

/*输入要求的课程名称和及格成绩 (不带默认值的)*/

use MySchool 
go
if exists ( select * from sysobjects where name = 'usp_unpass' )
drop procedure  usp_unpass
go

create proc usp_unpass
	@subname varchar(20) , 
	@score int 
as
declare @maxTime datetime , @SubNo int
select @SubNo = SubjectNo from Subject where SubjectName = @subname
select @maxTime = MAX(ExamDate) from Result where SubjectNo = @SubNo
declare @avgResult decimal(18,2)
select @avgResult = AVG(StudentResult) from Result  where SubjectNo = @SubNo and ExamDate =@maxTime

print '平均分是:'+convert(varchar(10) , @avgResult)
if(@avgResult >70)
begin
	print '考试成绩:优秀'
end
else
	print '考试成绩:较差'

print '参加'+@subname+'考试没有通过的学院有:'

select studentName ,Result.StudentNo , StudentResult  from Result 
inner join Student on Result.StudentNo = Student.StudentNo     
where SubjectNo = @SubNo and ExamDate =@maxTime and StudentResult<@score

go	

exec usp_unpass 'C# OOP' ,60
exec usp_unpass @subname = 'C# OOP' , @score = 80


/*输入要求的课程名称和及格成绩 (带默认值的)*/

use MySchool 
go
if exists ( select * from sysobjects where name = 'usp_unpass' )
drop procedure  usp_unpass
go

create proc usp_unpass
	
	@subname varchar(20),
	@score int = 60
as
declare @maxTime datetime , @SubNo int
select @SubNo = SubjectNo from Subject where SubjectName = @subname
select @maxTime = MAX(ExamDate) from Result where SubjectNo = @SubNo
declare @avgResult decimal(18,2)
select @avgResult = AVG(StudentResult) from Result  where SubjectNo = @SubNo and ExamDate =@maxTime

print '平均分是:'+convert(varchar(10) , @avgResult)
if(@avgResult >70)
begin
	print '考试成绩:优秀'
end
else
	print '考试成绩:较差'

print '参加'+@subname+'考试没有通过的学院有:'

select studentName ,Result.StudentNo , StudentResult  from Result 
inner join Student on Result.StudentNo = Student.StudentNo     
where SubjectNo = @SubNo and ExamDate =@maxTime and StudentResult<@score

go	

exec usp_unpass 'C# OOP' 
exec usp_unpass @subname = 'C# OOP' 

/*查询输出指定学期的课程 */
use MySchool
go
if exists(select * from sysobjects where name = 'usp_SubjectNameByName')
drop procedure usp_SubjectNameByName
go
create proc usp_SubjectNameByName
	@GradeName varchar(20) 
as
select GradeName , SubjectName , ClassHour   from Subject 
inner join Grade on Grade.GradeID = Subject.GradeID where GradeName = @GradeName
go

exec usp_SubjectNameByName null


/*根据输入的及格分数线查询获得本次考试未通过的学生信息 , 获得参加考试的学生人数和未通过的学生人数*/

use MySchool 
go
if exists ( select * from sysobjects where name = 'usp_unpassAndOut' )
drop procedure  usp_unpassAndOut
go

create proc usp_unpassAndOut
	@Wtg int output,							----输出参数, 未通过人数
	@All int output,							----输出参数, 参加考试总人数
	@subname varchar(20) ,						----输入参数,课程名称
	@score int  = 60							----输入参数,及格线
as
declare @maxTime datetime , @SubNo int
select @SubNo = SubjectNo from Subject where SubjectName = @subname
select @maxTime = MAX(ExamDate) from Result where SubjectNo = @SubNo
declare @avgResult decimal(18,2)
select @avgResult = AVG(StudentResult) from Result  where SubjectNo = @SubNo and ExamDate =@maxTime

print '平均分是:'+convert(varchar(10) , @avgResult)
if(@avgResult >70)
begin
	print '考试成绩:优秀'
end
else
	print '考试成绩:较差'

print '参加'+@subname+'考试没有通过的学院有:'

---未通过学员的信息如下
select studentName ,Result.StudentNo , StudentResult  from Result 
inner join Student on Result.StudentNo = Student.StudentNo     
where SubjectNo = @SubNo and ExamDate =@maxTime and StudentResult<@score
---获得参加考试的人数
select @All = count(0) from Result where  SubjectNo = @SubNo and ExamDate =@maxTime
---获得参加考试没有通过的人数
select @Wtg = count(0) from Result where  SubjectNo = @SubNo and ExamDate =@maxTime and StudentResult<@score 

go	


declare @wtg int ---参加考试的未通过的人数
declare @all int ---参加考试的总人数
exec usp_unpassAndOut @wtg output , @all output , 'Java Logic' 

declare @Jgl decimal(8,2)
set @Jgl = (@all-@wtg)/@all*100
print '未通过人数:'+convert(varchar(10) , @wtg)+'人 , 及格率是:'+convert(varchar(10) , @Jgl)+'%'

if(@wtg>0)
begin
	if(@Jgl>60)
	begin
		print '及格分数线不需要下调'
	end
	else
		print '及格分数线应下调'
end
else
print '本次考试成绩优良'


/**查询获得指定学期的课程名称、课时、统计改学期的总课程和总课时**/


use MySchool
go
if exists(select * from sysobjects where name = 'usp_SubjectNameByNameAll')
drop procedure usp_SubjectNameByNameAll
go
create proc usp_SubjectNameByNameAll
	@GradeName varchar(20) ,
	@AllSub int output , 
	@AllTime int output
as
select GradeName , SubjectName , ClassHour   from Subject 
inner join Grade on Grade.GradeID = Subject.GradeID where GradeName = @GradeName

select @AllSub = count(0) from Subject 
inner join Grade on Grade.GradeID = Subject.GradeID where GradeName = @GradeName

select @AllTime = sum(Subject.ClassHour) from Subject 
inner join Grade on Grade.GradeID = Subject.GradeID where GradeName = @GradeName

go

declare @allsub int , @alltime int
exec usp_SubjectNameByNameAll 'S1' , @allsub output , @alltime output
print '总课时是:'+convert(varchar(10) , @allsub)
print '总学时是:'+convert(varchar(10) , @alltime)
go




/*根据输入的及格分数线查询获得本次考试未通过的学生信息 , 获得参加考试的学生人数和未通过的学生人数(带错误处理的)*/

use MySchool 
go
if exists ( select * from sysobjects where name = 'usp_unpassAndOutError' )
drop procedure  usp_unpassAndOutError
go

create proc usp_unpassAndOutError
	@Wtg int output,							----输出参数, 未通过人数
	@All int output,							----输出参数, 参加考试总人数
	@subname varchar(20) ,						----输入参数,课程名称
	@score int  = 60							----输入参数,及格线
as
if(not @score between 0 and 100)
	begin
		raiserror('及格线必须在0-100之间',17,1)
		return
	end
declare @maxTime datetime , @SubNo int
select @SubNo = SubjectNo from Subject where SubjectName = @subname
select @maxTime = MAX(ExamDate) from Result where SubjectNo = @SubNo
declare @avgResult decimal(18,2)
select @avgResult = AVG(StudentResult) from Result  where SubjectNo = @SubNo and ExamDate =@maxTime

print '平均分是:'+convert(varchar(10) , @avgResult)
if(@avgResult >70)
begin
	print '考试成绩:优秀'
end
else
	print '考试成绩:较差'

print '参加'+@subname+'考试没有通过的学院有:'

---未通过学员的信息如下
select studentName ,Result.StudentNo , StudentResult  from Result 
inner join Student on Result.StudentNo = Student.StudentNo     
where SubjectNo = @SubNo and ExamDate =@maxTime and StudentResult<@score
---获得参加考试的人数
select @All = count(0) from Result where  SubjectNo = @SubNo and ExamDate =@maxTime
---获得参加考试没有通过的人数
select @Wtg = count(0) from Result where  SubjectNo = @SubNo and ExamDate =@maxTime and StudentResult<@score 

go	

declare @wtg int , @all int
exec usp_unpassAndOutError @wtg output , @all output , 'Java Logic'  , 109
print @@error
print @wtg
print @all

你可能感兴趣的:(数据库,存储,事务,索引,库,sql)