读书时遗失的笔记!现在偶尔的机会找到了!真的很不错的笔记!比较全面!在这里和大家共享!希望能帮到一些人!毕竟是在校时的产物!认知有限!如有错误还请帮忙指正!([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子句中省去此列)