读书时遗失的笔记!现在偶尔的机会找到了!真的很不错的笔记!比较全面!在这里和大家共享!希望能帮到一些人!毕竟是在校时的产物!认知有限!如有错误还请帮忙指正!([email protected])谢谢!
use master
go
if exists(select * from sysdatabases where name='student')
drop database student
--创建数据库
create database student
on
(
name='student',
filename='D:\DBExercise\sudent.mdf',
size=10,
filegrowth=10%,
maxsize=100
)
log on
(
name='student.ldf',
filename='D:\DBExercise\student.ldf',
size=5,
filegrowth=10%
)
go
--创建表
if exists(select * from sysobjects where name='stuInfo')
drop table stuInfo
if exists(select * from sysobjects where name='stuMarks')
drop table stuMarks
go
use student
go
create table stuInfo
(
stuName nvarchar(50) not null,
stuNo nvarchar(20) not null,
stuSex char(2) not null,
stuAge int not null,
stuSeat int identity(1,1) not null,
stuAddress nvarchar(100) not null
)
go
create table stuMarks
(
ExamNo nvarchar(20) not null,
stuNo nvarchar(20) not null,
writtenExam int not null,
labExam int not null
)
go
--向表中添加约束
alter table stuInfo
add constraint pk_stuNo primary key(stuNo)
alter table stuMarks
add constraint fk_stuNo foreign key(stuNo) references stuInfo(stuNo)
alter table stuInfo
add constraint df_stuAddress default('地址不详') for stuAddress
go
--向表中填充数据
insert into stuInfo(stuName,stuNo,stuSex,stuAge,stuAddress)
values('张秋离','s25301','男',19,'北京海淀')
insert into stuInfo(stuName,stuNo,stuSex,stuAge,stuAddress)
values('李斯文','s25303','女',20,'河南洛阳')
insert into stuInfo(stuName,stuNo,stuSex,stuAge,stuAddress)
values('李文才','s25302','男',17,default)
insert into stuInfo(stuName,stuNo,stuSex,stuAge,stuAddress)
values('欧阳俊雄','s25304','男',21,'新疆')
insert into stuInfo(stuName,stuNo,stuSex,stuAge,stuAddress)
values('梅嘲讽','s25318','女',18,default)
insert into stuMarks
values('s271811','s25303',93,59)
insert into stuMarks
values('s271813','s25302',63,91)
insert into stuMarks
values('s271816','s25301',90,83)
insert into stuMarks
values('s271817','s25318',63,53)
go
--检测表中数据
select * from stuInfo
select * from stuMarks
--本次考试的缺考人数
if exists(select * from sysobjects where name='newTable_1')
drop table newTable_1
select 应到人数=(select count(*) from stuInfo),
实到人数=(select count(*) from stuMarks),
缺考人数=((select count(*) from stuInfo)-(select count(*) from stuMarks)) into newTable_1
select * from newTable
--提取学员的成绩信息并保存结果,包括学员姓名,学号,笔试成绩和机试成绩,是否通过
if exists(select * from sysobjects where name='newTable_2')
drop table newTable_2
select stuName,stuInfo.stuNo,writtenExam,labExam,ispass=
case
when writtenExam>=60 and labExam>=60 then 1
else 0
end
into newTable_2 from stuInfo left join stuMarks on stuInfo.stuNo=stuMarks.stuNo
print('提分前的学员考试情况表')
select 学员姓名=stuName,学员编号=stuNo,
笔试成绩=case when writtenExam is null then '缺考'else convert(varchar(20),writtenExam) end,
机试成绩=case when labExam is null then '缺考' else convert(varchar(20),labExam) end,
是否通过=case when ispass=1 then '是' else '否' end
from newTable_2
--比较笔试平均分和机试平均分,较底者进行提分,但最高分不能超过97
declare @avg_write int ,@avg_lab int --声明两个变量
select @avg_write=avg(writtenExam), @avg_lab=avg(labExam)from newTable_2 where writtenExam is not null and labExam is not null
--print('笔试平均分:'+convert(nvarchar(20),@avg_write))
--print('机试平均分:'+convert(nvarchar(20),@avg_lab))
if( @avg_write<@avg_lab)
while(1=1)
begin
update newTable_2 set writtenExam=writtenExam+2
if(select max(writtenExam)from newTable_2)>=97
break
end
else
while(1=1)
begin
update newTable_2 set labExam=labExam+2
if(select max(labExam) from newTable_2)>=97
break
end
update newTable_2 set ispass=case
when writtenExam>=60 and labExam>=60 then 1
else 0
end
print('提分后的学员成绩表')
select * from newTable_2
--提分后,统计学员的成绩和通过情况
select 学员姓名=stuName,学员编号=stuNo,
笔试成绩=case when writtenExam is null then '缺考'else convert(varchar(20),writtenExam) end,
机试成绩=case when labExam is null then '缺考' else convert(varchar(20),labExam) end,
是否通过=case when ispass=1 then '是' else '否' end
from newTable_2
set noCount on
--提分后统学员的通过率
declare @count int ,@pass int
select @count=count(*) from stuInfo
select @pass=count(*) from newTable_2 where ispass=1
select 总人数=@count,
通过人数=@pass,
通过率=(convert(nvarchar(20),(@pass*100)/@count))+'%'
----------事务---------
if exists(select * from sysobjects where name='bank')
drop table bank
create table bank
(
name nvarchar(20) not null,
money money not null
)
go
insert into bank
values('Tom',800)
insert into bank
values('Jim',10)
alter table bank
add constraint ck_money check(money>1)
select * from bank
--Tom要转帐元给jim,有上表可知Tom的钱压根就没有那么多的,如果用update将Tom 的
--减少,而jim的增加,则会出现的情况是:Tom 的没有减少Jim却增加了
--这样银行就亏损了,显然银行是不同意这样的事情发生的
--那么为了使更改前后两者的数据保持一直我们就采取事务来处理类似的问题
begin transaction
set nocount on ====》设定不显示影响行数
declare @errorSum int
set @errorSum=0
update bank set money=money-1000 where name='Tom'
set @errorSum=@errorSum+@@error
--print(convert(nvarchar(20),@errorSum))
update bank set money=money+1000 where name='Jim'
set @errorSum=@errorSum+@@error
--print(convert(nvarchar(20),@errorSum))
--select * from bank --此时虽说系统报错了,但jim的钱还是多了,而Tom的却没有变化
if @errorSum<>0
begin
print('交易有误!')
rollback transaction
end
else
begin
print('交易成功!')
commit transaction
end
go
print('转帐后的系统存根:')
select * from bank
go
-----------索引---------------
--对于上面的stuMarks表创建索引
if exists(select name from sysindexes where name='ix_writtenExam')
drop index stuMarks.ix_writtenExam
create nonclustered index ix_writtenExam
on stuMarks(writtenExam)
with fillfactor=30 ===》它表示创建索引时每个索引页的数据填充率
go
--应用索引
select * from stuMarks
(index=ix_writtenExam)
where writtenExam between 60 and 90
---------视图----------
--========注:对视图的修改会影响到原始数据==========
if exists(select * from sysobjects where name='view_student')
drop view view_student
go
create view view_student
as
select 姓名=stuName,学号=stuInfo.stuNo,笔试成绩=writtenExam,机试成绩=labExam,平均分=(writtenExam+labExam)/2
from stuInfo left join stuMarks on stuInfo.stuNo=stuMarks.stuNo
go
select * from view_student
go
--===================存储过程=================
--所有的系统存储过程都是以sp_开头的,存放在master数据库中的
--***************常用系统存储过程的应用**************
exec sp_databases --列出当前系统中的存储过程
exec sp_renamedb 'oldname','newname' --改变数据库名称
use student
go
exec sp_tables
exec sp_columns stuInfo
exec sp_help stuInfo --查看stuInfo表的所有信息
exec sp_helpconstraint stuInfo --查看表的约束
exec sp_helpindex stuMarks --查看表的索引
exec sp_helptext 'view_writtenExam' --查看视图的语句文本
exec sp_stored_procedures --当前数据库中的存储过程列表
--系统存储过程xp_cmdshell可以实现DOS命令下的一些操作
--如果要创建一个数据库在D:\Issac中,但D盘中没有Issac文件夹,即可调用此存储过程实现创建
exec xp_cmdshell 'md D:\Issac',no_output --no_output是输出返回信息,可选
--==========自定义存储过程============
--***********不带参数的存储过程*************
use student
go
if exists(select * from sysobjects where name='proc_getAvgOfWrite')
drop procedure proc_getAvgOfWrite
go
create proc proc_getAvgOfWrite
as
declare @avgWrite float
select @avgWrite=avg(writtenExam)from stuMarks
print(convert(nvarchar(20),@avgWrite))
go
exec proc_getAvgOfWrite
--***************带参数的存储过程****************
--*******输入参数********
use student
go
if exists(select * from sysobjects where name='proc_getNotPass')
drop procedure proc_getNotPass
go
create proc proc_getNotPass
@writtenPass=60 int , --输入参数笔试及格线
@labPass=60 int --输入参数机试及格线
as
print('本次考试没有通过的学员:')
select stuName,stuInfo.stuNo,writtenExam,labExam from stuInfo inner join stuMarks on
stuInfo.stuNo=stuMarks.stuNo
where writtenExam<@writtenPass or labExam<@labPass
go
exec proc_getNotPass 70,65
--注:如果试题一般则调用存储过程时可以不带参数,如果试题偏易我们可以带上参数,
-- 至于带几个参数视情况而定,后面的参数形式多样.....
--**********输出参数**********
--如果调用的存储过程需要有返回值(一个或多个),则需要带有输出参数的存储过程
use student
go
if exists(select * from sysobjects where name='proc_getNotpass')
drop procedure proc_getNotpass
go
create proc proc_getNotpass
@notPassSum int output , --默认为输入参数
@writtePass int =60 ,
@labPass int
as
print('本次考试笔试及格线是:'+convert(nvarchar(20),@writtePass))
print('本次考试机试及格线是:'+convert(nvarchar(20),@labPass))
print('不及格的总体情况如表:')
select stuName,stuInfo.stuNo,writtenExam,labExam from stuInfo
inner join stuMarks on stuInfo.stuNo=stuMarks.stuNo
where writtenExam<@writtePass or labExam<@labPass
select @notPassSum=count(*)from stuMarks where writtenExam<@writtePass or labExam<@labPass
go
declare @sum int --定义变量用于存储返回的结果@notPassSum
exec proc_getNotpass @sum output ,75,63
print('本次考试没有通过的学员人数是:'+convert(nvarchar(20),@sum))
--===================触发器=================
user(id,name,age,address,telphone,email)
test(id,uid,content)
create trigger 触发器名
on 表或视图
for|after|instead of --操作时机
insert,update,delete
as
sql语句
eg1:
create trigger user_tri
on user
after insert
as
delete from test where id=(select count(*) from test)
go
********当执行对表 user 的 insert 操作时,会紧接着执行对 test 表的 delete 操作
eg2:
create trigger user_tri
on user
after insert
as
update test set content=content+user.id
from user,test
where user.id=test.uid
********当执行对 user 表 insert 的命令时,会执行对 test 表中 content 字段的修改
eg3:
create trigger user_tri
on user
after update
as
if update (age)
begin
raiserror('Error',10,1)
rollback transaction
end
*******当执行对 user 表中 age 执行 update 命令时会调用 raiserror,raiserror是联机丛书中定义的方法,返回服务器消息,并取消对 user 表中 age 的修改。
eg4:
create trigger user_tri
on user
after insert
as
if
(select count(*) from user,test
where user.id=test.uId)>
--可以在触发器逻辑中使用 @@ROWCOUNT 函数以区分单行插入和多行插入。
begin
delete order_test from order_test,inserted
where order_test.orderid=inserted.orderid and
inserted.customerid not in (select customerid from cust_test)
end
无效:
use northwind
alter table 表名
disable trigger 触发器名
重新有效:
use northwind
alter table 表名
enable trigger 触发器名
删除触发器
use northwind
drop trigger 触发器名,触发器名
select GetDate() --获取当前系统时间
select DateAdd(dd,3,(select GetDate())) --将指定的数值添加到指定的日期的部分中
select datediff(MM,'01/01/09','05/02/09') --两个日期间指定日期部分的差
select datepart(day,'01/23/2009') --日期指定部分的整数形式
select abs(-45) --绝对值
select ceiling(43.5) --大于或等于指定值的最小整数
select floor(43.5) --小于或等于指定值的最大整数
select charindex('Tom','Jim and Tom is good frients') --获得指定字符串在另一个字符串中的起始位置
select len('Issac') --指定字符串的长度
select upper('issac') --转换为大写
select Ltrim(' Tom ') --去除左边空格
select rtrim(' Tom ') --去除右边空格
select right('IssacAndTom',3) --从指定字符串右边返回指定长度字符串
select left('IssacAndTom',5) --从指定字符串左边返回指定长度字符串
select replace('IssacAndJim','Jim','Tom') --替换字符串中的字符
select stuff('IssacAndJim',6,3,'Or') --删除指定字符串指定为主的指定长度的字符串,并在该位置插入指定的新字符串
select power(5,2) --表达式的幂值
select round(43.456,2) --四舍五入到指定小数点后的位数
select current_user --当前用户的名
select system_user --当前所登陆的用户名字
select host_name() --当前登陆者登陆的计算机名
select datalength('Issac') --表达式长度
select * into A..accounts from B..account --将数据库B中的表account 复制到数据库A中并重命名为accounts
--得到表中无重复数据
select distinct * from tableName
--将表中重复数据去除(这里的重复是指:完全重复的记录,也即所有字段均重复的记录)
select distinct * into #Tmp from tableName
drop table tableName
select * into tableName from #Tmp
drop table #Tmp
--将表中重复数据去除(这里的重复是指部分关键字段重复的记录,比如Name字段重复,而其他字段不一定重复或都重复可以忽略。)
这类重复问题通常要求保留重复记录中的第一条记录,操作方法如下
假设有重复的字段为Name,Address,要求得到这两个字段唯一的结果集
select identity(int,1,1) as autoID, * into #Tmp from tableName
select min(autoID) as autoID into #Tmp2 from #Tmp group by Name,autoID
select * from #Tmp where autoID in(select autoID from #tmp2)
最后一个select即得到了Name,Address不重复的结果集(但多了一个autoID字段,实际写时可以写在select子句中省去此列)