SQL Server 數據庫基礎筆記分享(下)

前言sql

本文是我的學習SQL Server 數據庫時的以往筆記的整理,內容主要是對數據庫的基本增刪改查的SQL語句操做約束,視圖,存儲過程,觸發器的基本瞭解。數據庫

注:內容比較基礎,適合入門者對SQL Server 數據庫的瞭解!!!併發

正文tcp

1.子查詢函數

--把一個查詢結果做爲另一個查詢的查詢源
select * from (select * from Student where tbage between 3 and 5)
as ct where tbname=5 --ct是新創的表名學習

--把另一個查詢的結果做爲當前查詢的條件來使用。
--子查詢中=、!= 、< 、> 、<= 、>=以後只能返回單個值,若是多個值就會報錯
--解決辦法 能夠用in 代替
select * from Student
where tbage in(select tbage from Student where tbname=3)fetch

select * from Student
where tbage=(select tbage from Student where tbname=3)spa

》》》》》》子查詢分頁《《《《《《日誌

--1》顯示第一頁的數據
--分頁查詢的時候首先是將數據排序
select * from Student order by id descserver

--2》第一頁 顯示5條數據
select Top 5 * from Student order by id desc

--3》第二頁
select top 5 * from Student
where id not in (select top 5 * from Student order by id desc)
order by id desc

--4》第三頁
select top 5 * from Student
where id not in (select top (2*5) * from Student order by id desc)
order by id desc

》》》開窗函數分頁《《《

--第七頁數據 每頁5條數據
--over屬於開窗函數

select * from
(
select * ,row_number() over( order by id desc) as paixu from Student
) as tbl
where tbl.paixu between 6*5+1 and 7*5

2.連表查詢

--查詢全部學生的姓名、年齡及所在班級 (班級在另外一個表中)
--當多個列在不一樣的表中時,要跨表查詢,因此通常可使用inner join
--tc ts是對錶名起的別名
select
ts.tsname,
ts.tsage,
tc.tclassname
from TblStudent as ts
inner join TblClass as tc on ts.tsclassid=tc.tclassid(只查詢兩個表中都有的數據)

--》》》full join 是查詢全部的數據(沒有的爲空)

---子查詢寫法
select
tsname,
tsage,
班級名稱=(select tclassname from TblClass where TblClass.tclassid=TblStudent.tsclassid)
from TblStudent

--查詢學生姓名、年齡、班級及成績(成績屬於第三張表)
select
ts.tsname,
ts.tsage,
tc.tclasssname,
tscore.tenglish,
tscore.tmath
from TblStudent as ts
inner join TblClass as tc on ts.tsclassid=tc.tclassid 
inner join TblScore as tscore on tscore.tsid=ts.tsid

 

--》》》左外聯接(左聯接)

--查詢沒有參加考試的學生的姓名與編號
--把左表(left join 關鍵字左邊的表)中的所有記錄都顯示出來,對於那些在右表中能找到匹配的記錄,顯示對應匹配數據,對於那些右表中找不到匹配的記錄顯示爲null
select
ts.tsid,
ts.tsname,
TblScore.*
from TblStudent as ts
left outer join TblSore.tsid=ts.tsid   --outer能夠不寫

--》》》右外聯接
--表示要將右表(right join 右邊的表)中的全部數據都顯示,左表中只顯示那些匹配的數據。

select
ts.tsid,
ts.tsname,
TblScore.*
from TblStudent as ts
right outer join TblSore.tsid=ts.tsid

--右外聯與左外聯都是先將匹配的數據找到,而後再將那些沒有匹配的數據添加進來,(注意:不是一塊兒查詢出來的,有前後順序)

--》》》練習:查詢全部學生(參加和未參加的考試)的學生姓名、年齡、成績,若是沒有參加考試顯示缺考,若是小於english或者math 小於60分顯示不及格
select
ts.tsname,
ts.tsage,
tscore.tsid,
case
when tscore.tenglish is null then '缺考'
else convert(varchar(10),tscore.tenglish)
end as 英語成績,
case
when tscore.tmath id null then '缺考'
else convert (varchar(10),tscore.tmath)
end as 數學成績,
是否報考=
case
when tscore.tscoreid is null then '是'
else '否'
end
from TblStudent as ts
left join TblScore as tscore on ts.tsid=tscore.tsid

3.視圖

視圖自己並不存儲數據,只是存儲的查詢語句,若是把真實表中的數據修改後,則經過視圖查詢到的結果也變了。

視圖的目的是方便查詢,因此通常狀況下不能對視圖進行增刪改查


--在視圖中的查詢語句,必須爲每一列建立一個列名
create view vw2
as
select
tsname,
case
when tsage>13 and tsage<=16 then '少年'
when tsage>50 then '老年'
else '青壯年'
end as 稱呼
from TblStudent

--在視圖中不能使用order by語句。除非:另外還指定了top 或for xml
--錯誤
create view vw3
as
select * from TblStudent order by tsage desc

--正確
create view vw3
as
select top 3 * from TblStudent order by tsage desc

4.聲明變量與使用

--》》》局部變量
--聲明變量
declare @name varchar(10)
declare @age int

--賦值
set @name='yhz'
set @age=17

--輸出值
print @name
print @age

--使用set與select爲變量賦值的區別
declare @rcount int
set @rcount=(select count(*) from TblStudent)
print @rcount

declare @rcount int
select @rcount=count(*) from TblStudent
print @rcount


--》》》全局變量
print @@language
print @@version
print 'aaa'+100
--經過判斷@@error變量中是否不爲0,就能夠判斷上一條sql語句執行是否出錯了
--若是@@error爲0,表示上一條sql語句執行沒出錯,若是@@error不爲0,則表示上一條sql語句出錯了。
print@@error

--》》》經過while計算1-100之間全部奇數的和

--聲明變量並初始化

declare @sum int=0
declare @i int =1
while @i<=100
begin
if @i%2<>0
begin
set @sum=@sum+@i
end
end
print @sum

5.事務

事務有四個屬性:原子性 一致性 隔離性 持久性
原子性:對於數據修改,要麼全都執行,要麼全都不執行
一致性:當數據完成時,數據必須處於一致狀態
隔離性:對數據進行修改的全部併發事務時彼此隔離的。這代表事務必須是獨立的,它不該以任何方式依賴於或影響其餘事務
永久性:事務完成後,他對數據庫的修改被永久保持,事務日誌可以保持事務的永久性

--打開事務
begin transaction

--提交事務
commit transaction

--回滾事務
rollback transaction


--帳戶A給帳戶B轉帳 當一方出問題時,兩個語句都不執行
begin tran
declare @sum int=0
update bank set balance =balance-1000 where cid='0001'
set @sum=@sum+@@error
update banl set balance =balance+1000 where cid='0002'
set @sum=@sum+@@error

if @sum<>0
begin
rollback tran
print '回滾'
end
else
begin
commit tran
print '提交了'
end

6.存儲過程

--建立一個自定義的存儲過程
create proc usp_HelloWorld
as
begin
print 'hello world'
end

--輸出存儲過程
exec usp_HelloWorld

--建立一個存儲過程計算兩個數的和
create procedure usp_Add
@num1 int,
@num2 int
as
begin
print @num1+@num2
end

--輸出值
exec usp_Add 100,230


--存儲過程當中的參數的問題
--存儲過程若是有參數,則調用的時候必須爲參數賦值
exec usp_Add --不傳參數則報錯


--第二個參數若是用戶不傳,則有一個默認值
create procedure usp_Add
@num1 int,
@num2 int 1000 --爲存儲過程的參數設置默認值
as
begin
print @num1+@num2
end

--建立分頁存儲過程
create proc usp_PageBum
@pageSize int, --每頁顯示的數量
@pageIndex int --第幾頁
as
begin
select * from (select *,row_number()over (order by CityID asc)as num from S_City )as s
where s.num between (@pageIndex -1)*@pageSize +1 and @pageIndex *@pageSize
end
--查詢第5頁內容每頁顯示10條數據
exec usp_PageBum 10,5

--刪除一個存儲過程
drop proc usp_Add

7.觸發器

儘可能避免在觸發器中執行耗時操做,由於觸發器會與sql語句認爲在同一個事務中(事務不結束,就沒法釋放鎖)

--建立插入數據觸發器
create trigger tri_Teacher_insert_after
on Teacher after insert
as
begin
declare @id int
declare @name varchar(10)
declare @phone int
declare @mail varchar(50)
select @id=tcid,@name=tcname,@phone=tcphone,@mail=tcmail from inserted

print @id
print @name
print @phone
print @mail
end

--插入數據
insert into Teacher values('網名好','12352536','Wjifdfji@qq.com')


--建立刪除數據觸發器
--不能有主鍵
create trigger tri_Teacher_after
on Teacher after delete
as
begin
insert into TeacherBak
select * from deleted
end

--刪除數據
--sql server中的觸發器是表級觸發器,不管刪除多少行或者插入多少行,只觸發一次
--是按語句來觸發的,每次執行一次語句,觸發一次觸發器
delete from Teacher where tcid>18

8.遊標

--1.定義遊標
declare cur_Student cursor fast_forward for select * from Student

--2.打開遊標
open cur_Student

--2.1 對遊標的操做
--將每條數據讀取並輸出

--2.1.1將遊標向後移動一條
fetch next from cur_Student

--將遊標循環向後移動,直到末尾
while @@fetch_status=0
begin
fetch next from cur_Student
end


--3.關閉遊標
close cur_Student

--4.釋放資源
deallocate cur_Student

9.(補充)全局臨時表,局部臨時表

局部臨時表:表名以#爲開頭。只在當前會話中有效,不能跨鏈接訪問。若是直接在鏈接會話中建立,則當前鏈接斷開後刪除,若是是在存儲過程當中建立的,則存儲過程執行完畢後刪除

全局臨時表:表名以##爲開頭。多個會話可共享全局臨時表。當建立全局臨時表的會話斷開,而且沒有用戶正在訪問全局臨時表時刪除

10.(補充)約束

--刪除一列(EmpAddress列)
alter table Class drop column EmpAddress

--增長一列(增長一列EmpAddr varchar(1000))
alter table Class Add EmpAddr varchar(1000)

--修改一下Emp 的數據類型(varchar(200))
alter table Class alter column Emp varchar(200)

--爲EmpId增長一個主鍵約束
alter table Class add constraint PK_Class_EmpId primary key(EmpId)

--爲EmpName增長一個惟一約束
alter table Class add constraint UQ_Class_EmpName unique(EmpName)

--爲性別增長一個默認約束,默認爲男
alter table Class add constraint DF_Class_EmpGender default('男') for EmpGender

--爲年齡增長一個檢查約束,年齡必須在1—120歲之間(包含)
alter table Class add constraint CK_Class_EmpAge check(EmpAge>=0 and EmpAge<=120)

--增長外鍵約束,表Class中有一列EmpDeptId引用Student表中的DeptId
alter table Class add EmpDeptId int not null
alter table Student add constraint PK_Student_DeptId primary key(DeptId)

alter table Class add constraint FK_Class_Student foreign key(EmpDeptId)
references Student(DeptId)


--一條語句刪除多個約束,約束名用 逗號 隔開
alter table Class drop constraint
PK_Student_DeptId,
FK_Class_Student,
CK_Class_EmpAge


--用一條語句爲表增長多個約束
alter table Class add
constraint PK_Student_DeptId primary key(DeptId),
constraint CK_Class_EmpAge check(EmpAge>=0 and EmpAge<=120),
add constraint DF_Class_EmpGender default('男') for EmpGender

後記

筆記不全,還請見諒!但願對你有所提升。

相關文章
相關標籤/搜索