1. 程式人生 > 其它 >SQL儲存過程,事務,觸發器

SQL儲存過程,事務,觸發器

儲存過程
概念:資料庫中一個內建的程式段,當執行儲存過程到時候,就會將其內部的程式碼執行一遍。
優點:1執行速度'比較'快 2安全性比較高(傳參方式決定)
語法:procdurce過程 簡稱proc

解釋:1.執行效率快:SQL語句在執行的時候,"每次"執行,資料庫都會進行編譯。
儲存過程是在建立的時候編譯,一旦建立成功,就不會再進行編譯。由於少了一次編譯,所以速度提升了。
2.儲存過程可以防止SQL注入式攻擊

SQL注入攻擊:
如何防範:1過濾特殊的字元 ' " \ /
2md5
3使用儲存過程

--1.無參儲存過程
create proc pr_stuquery
as
select stuid from Students
go

--2.有引數的儲存過程
create proc pr_stuquerybyid
@stuID int
as
select * from Students where stuID=@stuID

go
exec pr_stuquerybyid 5

--3有返回值的儲存過程
--3.1return型別:在需要返回的數字前加return
--限制:1只能返回數字
--2只能返回一個
alter proc pr_insertstudent_return
@stuname nvarchar(50),
@hobby nvarchar(500),
@createtime datetime
as
insert into Students values(@stuname,@hobby,@createtime)
--希望返回一個主鍵
--全域性變數@@identity獲取新插入資料庫的主鍵
return @@identity
go

--宣告變數
declare @newid int
exec @newid=pr_insertstudent_return 'admin','程式設計','2021-05-24'
select @newid

--3.2output型別
--output不限制返回值的個數和返回值的資料型別
create proc pr_insertstudent_output
@stuname nvarchar(50),
@hobby nvarchar(500),
@createtime datetime,
@newid int output,--註明引數為output型別
@helloworld nvarchar(50) output
as
insert into Students values(@stuname,@hobby,@createtime)
--希望返回一個主鍵
--全域性變數@@identity獲取新插入資料庫的主鍵
set @newid=@@IDENTITY
set @helloworld='helloworld'
go

declare @newid int
declare @helloworld nvarchar(50)
exec pr_insertstudent_output 'admin','程式設計','2021-05-24',@newid output,@helloworld output
select @newid as nid,@helloworld

事務:

例:
……關鍵語句講解………
BEGIN TRANSACTION
/*--定義變數,用於累計事務執行過程中的錯誤--*/
DECLARE @errorSum INT
SET @errorSum=0 --初始化為0,即無錯誤
/*--轉賬:張三的賬戶少1000元,李四的賬戶多1000元*/
UPDATEbankSET currentMoney=currentMoney-1000
WHERE customerName='張三'
SET @errorSum=@errorSum+@@error
UPDATE bank SET currentMoney=currentMoney+1000
WHERE customerName='李四'
SET @errorSum=@errorSum+@@error --累計是否有錯誤
IF @errorSum<>0 --如果有錯誤
BEGIN
print '交易失敗,回滾事務'
ROLLBACK TRANSACTION
END?
ELSE
BEGIN
print '交易成功,提交事務,寫入硬碟,永久的儲存'
COMMIT TRANSACTION
END
GO
print '檢視轉賬事務後的餘額'
SELECT * FROM bank?
GO

觸發器:
概念:觸發器是一個特殊的儲存過程。 特殊在觸發器是自動執行的,不需要進行呼叫。

需求:希望刪除使用者的時候,將使用者的日誌也進行刪除。

思考:如果我有很多個使用者都要刪除

inserted新增臨時表:存放新資料
deleted 刪除臨時表:存放舊資料

delete from Students where stuID in (33,34,35,36)

--刪除的觸發器
create trigger tr_deleteuser_deletelog
on Students for delete
as
   --從刪除臨時表中得到剛才清除的資料
   declare @stuid int
   select @stuid=stuid from deleted
   delete from logs where stuid=@stuid
go

--新增臨時表
--向a表插入一條記錄,此時我希望把資料在b表中也插入一條
alter trigger tr_inserta_insertb
on a for insert
as
    declare @aid int 
    declare @aname nvarchar(50)
     select @aid=aid ,@aname=aname from inserted
    insert into b values(@aid,@aname,0)
go

 insert into a values('測試員AA')
select * from a
select * from b


update Students set isdelete=1000 where stuID=6
--更新
alter trigger tr_deletestu_deletelog
on students for update
as
     if(UPDATE(isdelete))
     begin
         declare @isdelete int,@oldisdelete int  
         declare @stuid int
         select @isdelete=isdelete from inserted
         select @stuid=stuid,@oldisdelete=isdelete from deleted
         update logs set isdelete=@isdelete where stuid=@stuid
         --希望你列印原來的邏輯狀態
         print @oldisdelete
     end
go

update Students set stuName='admin' where stuID=6


--總結:
--1觸發器她的使用場景並不是很大,因為她比較麻煩,效率低。
--2觸發器在邏輯關係複雜的情況下,可能會導致資料處理不完整。