讀書時遺失的筆記!現在偶爾的機會找到了!真的很不錯的筆記!比較全面!在這裏和大家共享!希望能幫到一些人!畢竟是在校時的產物!認知有限!如有錯誤還請幫忙指正!([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子句中省去此列)