數據庫編程基礎(存儲過程和觸發器)

存儲過程

存儲過程概念

(百度百科)
存儲過程(Stored Procedure)是在大型數據庫系統中,一組爲了完成特定功能的SQL 語句集,它存儲在數據庫中,一次編譯後永久有效,用戶通過指定存儲過程的名字並給出參數(如果該存儲過程帶有參數)來執行它。存儲過程是數據庫中的一個重要對象。在數據量特別龐大的情況下利用存儲過程能達到倍速的效率提升。

存儲過程的作用

不使用存儲過程時,所有的數據處理都在客戶端完成;而使用存儲過程時,可以使數據處理在服務器端完成。
可以避免在網絡上傳輸大量無用的信息或原始數據,只需要傳輸調用存儲過程的指令和數據庫服務器返回的處理結果。
把完成某一數據庫處理的功能設計爲存儲過程,則可以在各個程序中反覆調用,從而減輕程序的編寫工作量。
也可以利用存儲程序間接實現一些安全控制功能。

創建和執行存儲過程

創建存儲過程的基本格式:
在這裏插入圖片描述
說明:
創建存儲過程通常是在數據庫設計和開發階段完成的。
存儲過程可以嵌套,即在一個存儲過程中可以調用另外一個存儲過程。
存儲過程一般用來完成數據查詢和數據處理操作;
在存儲過程中不可以使用創建數據庫對象的語句(如create table等各種create語句)。

執行存儲過程的格式:
在這裏插入圖片描述
修改存儲過程:
在這裏插入圖片描述
刪除存儲過程:
在這裏插入圖片描述

應用舉例

--例1:使用簡單過程。
--下面的存儲過程將從表中返回所有職工信息(姓名、倉庫號、工資、所在城市)。這個存儲過程不使用任何參數。
CREATE PROCEDURE uspGetAllEmp  --  CREATE PROC uspGetAllEmp 
AS
    SELECT 姓名,倉庫.倉庫號,工資,城市 AS 所在城市
    FROM 倉儲.倉庫 JOIN 基礎.職工 ON 倉庫.倉庫號=職工.倉庫號
--例2:使用帶有參數的簡單過程。
--下面的存儲過程只從表中返回指定城市的職工信息。該存儲過程需要提供精確匹配的參數值。
CREATE PROCEDURE uspGetEmp1
@city char(10)
AS
    SELECT *
    FROM 基礎.職工 
    WHERE 倉庫號 IN
       (SELECT 倉庫號 
        FROM 倉儲.倉庫
        WHERE 城市=@city)

--爲了得到“北京”的職工信息,可通過以下方式執行存儲過程uspGetEmp1:
EXECUTE uspGetEmp1 @city='北京'
EXECUTE uspGetEmp1 '北京'
--例3:使用帶有參數和返回值的簡單過程。
--下面的存儲過程查詢指定倉庫訂單金額大於指定值的訂單數,查詢結果通過RETURN語句返回:
CREATE PROCEDURE uspGetOrderNum
@whno char(6)='wh1',@sum money    --默認值爲'wh1'
AS
 DECLARE @count int
 SELECT  @count=COUNT(*) 
 FROM 訂貨.訂購單
 WHERE 金額>=@sum AND 經手人 IN
	(SELECT 職工號
	 FROM 基礎.職工
	 WHERE 倉庫號=@whno)
 RETURN @count

--下面的語句調用存儲過程uspGetOrderNum查詢WH1倉庫金額大於1000的訂單數:
DECLARE @count int
EXECUTE @count= uspGetOrderNum 'WH1',1000
PRINT 'WH1倉庫金額在1000以上的訂單數是:'+STR(@count)

DECLARE @count int
EXECUTE @count= uspGetOrderNum @sum=1000,@whno='WH1'
PRINT 'WH1倉庫金額在1000以上的訂單數是:'+STR(@count)
--例4:使用帶有通配符參數的簡單過程。
--下面的uspGetSup存儲過程用於只從表中返回指定的一些供應商的信息(提供供應商名稱中的關鍵字)。此存儲過程通過參數的模式匹配完成查詢,如果未提供參數,則返回全部供應商信息。
CREATE PROCEDURE 訂貨.uspGetSup
@sname varchar(20)='%'
AS
    SELECT * FROM 訂貨.供應商
    WHERE 供應商名 LIKE @sname

--以下執行存儲過程的命令將返回供應商名稱中含有“北京”的供應商信息:
EXECUTE 訂貨.uspGetSup @sname='%北京%'
--以下執行存儲過程的命令將返回全部的供應商信息(沒有提供參數):
EXECUTE 訂貨.uspGetSup

--例5. 使用 OUTPUT 參數
--指定供應商所經手訂購單的數量和平均金額,一個參數傳入指定供應商名,一個參數傳出計算的平均金額,計算的訂單數量用RETURN語句返回
--drop proc uspGetAvg
create proc uspGetAvg
@sname char(20),@avg money output
as
    declare @count int
	select @count=count(*),@avg=avg(金額)
	from 訂貨.訂購單
	where 供貨方=
		(select 供應商號
		from 訂貨.供應商
		where 供應商名=@sname)
	return @count

--調用
declare @avgout money ,@countout int
exec @countout=uspGetAvg @sname='華通電子公司',@avg=@avgout output
print '華通電子公司的訂單數是:'+str(@countout)+',平均金額是:'+str(@avgout,6,2)

--1個輸入參數,2個輸出參數
create proc uspGetAvg2
	@sname char(20),
	@avg money output,
	@count int output
as
	select @count=count(*),@avg=avg(金額)
	from 訂貨.訂購單
		where 供貨方=
		(select 供應商號
		from 訂貨.供應商
		where 供應商名=@sname)

declare @avgout money ,@countout int
exec uspGetAvg2 @sname='華通電子公司',@avg=@avgout output,@count=@countout output
print '華通電子公司的訂單數是:'+str(@countout)+',平均金額是:'+str(@avgout,6,2)

觸發器

觸發器的概念和用途

觸發器可以看作是一類特殊的存儲過程,它在滿足某個特定條件時自動觸發執行。觸發器和存儲過程同是提高數據庫服務器性能的有力工具。
觸發器是一種程序或是一種過程,它和存儲過程一樣是事先設計好存儲在數據庫中的,與存儲過程不同的是觸發器不需要專門調用或執行,觸發器是在某個特定條件發生時自動觸發執行的。
分爲DML(數據操作語言)觸發器、DDL(數據定義語言)觸發器和LOGIN觸發器
DML觸發器在執行數據操作語言(update、insert和delete)時觸發;
DDL觸發器在執行數據定義語言時觸發;
LOGIN觸發器在有用戶登錄時觸發。

DML觸發器也是一個數據庫對象,但DML觸發器依附於表(或視圖)。
DML觸發器分爲插入觸發器、刪除觸發器和更新觸發器三類

觸發器的三個要素:
定義觸發器的表(或視圖)
激活觸發器的數據操作語句
採取的動作

建立和刪除觸發器

建立:
在這裏插入圖片描述
刪除:
在這裏插入圖片描述
比較for觸發器和instead of觸發器的區別

--instead of不能插入表中
create trigger wh_trigger1
on 倉儲.倉庫 
instead of insert
as 
	print 'instead of 觸發器'
--使用觸發器
insert into 倉儲.倉庫 values('WH8','杭州',450)

drop trigger wh_trigger1
--for可以把數據插入表中
create trigger wh_trigger1
on 倉儲.倉庫 
for insert 
as 
	print 'instead of 觸發器'

deleted表和inserted表
當DML觸發器激活時系統會自動產生兩個特殊的臨時表:deleted表和inserted表
當發生insert操作時新插入的記錄也存儲在inserted表
當發生deleted操作時被刪除的記錄也存儲在deleted表
當發生update操作時修改前的舊記錄也存儲在deleted表、修改後的新紀錄也存儲在inserted表
可以使用deleted表和inserted表判斷正在操作的記錄是否符合要求,從而檢查錯誤並採取相應的措施。
可以擴展表之間的參照完整性。
deleted表和inserted表只在觸發器內可用,一旦觸發器完成任務,這兩個系統產生的臨時表將自動刪除。

觸發器應用舉例

CREATE TRIGGER reminder1
ON 倉儲.庫存
FOR UPDATE
AS
	DECLARE @amount int
	SELECT @amount=數量 FROM inserted
	IF @amount<5
		RAISERROR ('庫存數量小於5',16,10)

UPDATE 倉儲.庫存 SET 數量=數量-3
where 倉庫號='WH1' AND 器件號='P3'
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章