您好,登錄后才能下訂單哦!
這篇文章主要講解了“SQL Server中函數、存儲過程與觸發器怎么用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“SQL Server中函數、存儲過程與觸發器怎么用”吧!
函數分為(1)系統函數,(2)自定義函數。
其中自定義函數又可以分為(1)標量值函數(返回單個值),(2)表值函數(返回查詢結果)
本文主要介紹自定義函數的使用。
(1)編寫一個函數求該銀行的金額總和
create function GetSumCardMoney() returns money as begin declare @AllMOney money select @AllMOney = (select SUM(CardMoney) from BankCard) return @AllMOney end
函數調用
select dbo.GetSumCardMoney()
上述函數沒有參數,下面介紹有參數的函數的定義及使用
(2)傳入賬戶編號,返回賬戶真實姓名
create function GetNameById(@AccountId int) returns varchar(20) as begin declare @RealName varchar(20) select @RealName = (select RealName from AccountInfo where AccountId = @AccountId) return @RealName end
函數調用
print dbo.GetNameById(2)
(3)傳遞開始時間和結束時間,返回交易記錄(存錢取錢),交易記錄中包含 真實姓名,卡號,存錢金額,取錢金額,交易時間。
方案一(邏輯復雜,函數內容除了返回結果的sql語句還有其他內容,例如定義變量等):
create function GetExchangeByTime(@StartTime varchar(30),@EndTime varchar(30)) returns @ExchangeTable table ( RealName varchar(30), --真實姓名 CardNo varchar(30), --卡號 MoneyInBank money, --存錢金額 MoneyOutBank money, --取錢金額 ExchangeTime smalldatetime --交易時間 ) as begin insert into @ExchangeTable select AccountInfo.RealName,CardExchange.CardNo,CardExchange.MoneyInBank, CardExchange.MoneyOutBank,CardExchange.ExchangeTime from CardExchange left join BankCard on CardExchange.CardNo = BankCard.CardNo left join AccountInfo on BankCard.AccountId = AccountInfo.AccountId where CardExchange.ExchangeTime between @StartTime+' 00:00:00' and @EndTime+' 23:59:59' return end
函數調用
select * from GetExchangeByTime('2018-6-1','2018-7-1')
方案二(邏輯簡單,函數內容直接是一條sql查詢語句):
create function GetExchangeByTime(@StartTime varchar(30),@EndTime varchar(30)) returns table as return select AccountInfo.RealName,CardExchange.CardNo,CardExchange.MoneyInBank, CardExchange.MoneyOutBank,CardExchange.ExchangeTime from CardExchange left join BankCard on CardExchange.CardNo = BankCard.CardNo left join AccountInfo on BankCard.AccountId = AccountInfo.AccountId where CardExchange.ExchangeTime between @StartTime+' 00:00:00' and @EndTime+' 23:59:59' go
函數調用:
select * from GetExchangeByTime('2018-6-19','2018-6-19')
(4)查詢銀行卡信息,將銀行卡狀態1,2,3,4分別轉換為漢字“正常,掛失,凍結,注銷”,根據銀行卡余額顯示銀行卡等級 30萬以下為“普通用戶”,30萬及以上為"VIP用戶",分別顯示卡號,身份證,姓名,余額,用戶等級,銀行卡狀態。
方案一:直接在sql語句中使用case when
select * from AccountInfo select * from BankCard select CardNo 卡號,AccountCode 身份證,RealName 姓名,CardMoney 余額, case when CardMoney < 300000 then '普通用戶' else 'VIP用戶' end 用戶等級, case when CardState = 1 then '正常' when CardState = 2 then '掛失' when CardState = 3 then '凍結' when CardState = 4 then '注銷' else '異常' end 卡狀態 from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId
方案二:將等級和狀態用函數實現
create function GetGradeByMoney(@myMoney int) returns varchar(10) as begin declare @result varchar(10) if @myMoney < 3000 set @result = '普通用戶' else set @result = 'VIP用戶' return @result end go create function GetStatusByNumber(@myNum int) returns varchar(10) as begin declare @result varchar(10) if @myNum = 1 set @result = '正常' else if @myNum = 2 set @result = '掛失' else if @myNum = 3 set @result = '凍結' else if @myNum = 4 set @result = '注銷' else set @result = '異常' return @result end go
函數調用實現查詢功能
select CardNo 卡號,AccountCode 身份證,RealName 姓名,CardMoney 余額, dbo.GetGradeByMoney(CardMoney) 賬戶等級,dbo.GetStatusByNumber(CardState) 卡狀態 from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId
(5)編寫函數,根據出生日期求年齡,年齡求實歲,例如:
生日為2000-5-5,當前為2018-5-4,年齡為17歲
生日為2000-5-5,當前為2018-5-6,年齡為18歲
測試數據如下:
create table Emp ( EmpId int primary key identity(1,2), --自動編號 empName varchar(20), --姓名 empSex varchar(4), --性別 empBirth smalldatetime --生日 ) insert into Emp(empName,empSex,empBirth) values('劉備','男','2008-5-8') insert into Emp(empName,empSex,empBirth) values('關羽','男','1998-10-10') insert into Emp(empName,empSex,empBirth) values('張飛','男','1999-7-5') insert into Emp(empName,empSex,empBirth) values('趙云','男','2003-12-12') insert into Emp(empName,empSex,empBirth) values('馬超','男','2003-1-5') insert into Emp(empName,empSex,empBirth) values('黃忠','男','1988-8-4') insert into Emp(empName,empSex,empBirth) values('魏延','男','1998-5-2') insert into Emp(empName,empSex,empBirth) values('簡雍','男','1992-2-20') insert into Emp(empName,empSex,empBirth) values('諸葛亮','男','1993-3-1') insert into Emp(empName,empSex,empBirth) values('徐庶','男','1994-8-5')
函數定義:
create function GetAgeByBirth(@birth smalldatetime) returns int as begin declare @age int set @age = year(getdate()) - year(@birth) if month(getdate()) < month(@birth) set @age = @age - 1 if month(getdate()) = month(@birth) and day(getdate()) < day(@birth) set @age = @age -1 return @age end
函數調用實現查詢
select *,dbo.GetAgeByBirth(empBirth) 年齡 from Emp
觸發器分類:(1) “Instead of”觸發器(2)“After”觸發器
“Instead of”觸發器:在執行操作之前被執行
“After”觸發器:在執行操作之后被執行
觸發器中后面的案例中需要用到的表及測試數據如下:
--部門 create table Department ( DepartmentId varchar(10) primary key , --主鍵,自動增長 DepartmentName nvarchar(50), --部門名稱 ) --人員信息 create table People ( PeopleId int primary key identity(1,1), --主鍵,自動增長 DepartmentId varchar(10), --部門編號,外鍵,與部門表關聯 PeopleName nvarchar(20), --人員姓名 PeopleSex nvarchar(2), --人員性別 PeoplePhone nvarchar(20), --電話,聯系方式 ) insert into Department(DepartmentId,DepartmentName) values('001','總經辦') insert into Department(DepartmentId,DepartmentName) values('002','市場部') insert into Department(DepartmentId,DepartmentName) values('003','人事部') insert into Department(DepartmentId,DepartmentName) values('004','財務部') insert into Department(DepartmentId,DepartmentName) values('005','軟件部') insert into People(DepartmentId,PeopleName,PeopleSex,PeoplePhone) values('001','劉備','男','13558785478') insert into People(DepartmentId,PeopleName,PeopleSex,PeoplePhone) values('001','關羽','男','13558788785') insert into People(DepartmentId,PeopleName,PeopleSex,PeoplePhone) values('002','張飛','男','13698547125')
(1)假設有部門表和員工表,在添加員工的時候,該員工的部門編號如果在部門表中找不到,則自動添加部門信息,部門名稱為"新部門"。
編寫觸發器:
create trigger tri_InsertPeople on People after insert as if not exists(select * from Department where DepartmentId = (select DepartmentId from inserted)) insert into Department(DepartmentId,DepartmentName) values((select DepartmentId from inserted),'新部門') go
測試觸發器:
insert People(DepartmentId,PeopleName,PeopleSex,PeoplePhone) values('009','趙云','男','13854587456')
我們會發現,當插入趙云這個員工的時候會自動向部門表中添加數據。
(2)觸發器實現,刪除一個部門的時候將部門下所有員工全部刪除。
編寫觸發器:
create trigger tri_DeleteDept on Department after delete as delete from People where People.DepartmentId = (select DepartmentId from deleted) go
測試觸發器:
delete Department where DepartmentId = '001'
我們會發現當我們刪除此部門的時候,同時會刪除該部門下的所有員工
(3)創建一個觸發器,刪除一個部門的時候判斷該部門下是否有員工,有則不刪除,沒有則刪除。
編寫觸發器:
drop trigger tri_DeleteDept --刪除掉之前的觸發器,因為當前觸發器也叫這個名字 create trigger tri_DeleteDept on Department Instead of delete as if not exists(select * from People where DepartmentId = (select DepartmentId from deleted)) begin delete from Department where DepartmentId = (select DepartmentId from deleted) end go
測試觸發器:
delete Department where DepartmentId = '001' delete Department where DepartmentId = '002' delete Department where DepartmentId = '003'
我們會發現,當部門下沒有員工的部門信息可以成功刪除,而部門下有員工的部門并沒有被刪除。
(4)修改一個部門編號之后,將該部門下所有員工的部門編號同步進行修改
編寫觸發器:
create trigger tri_UpdateDept on Department after update as update People set DepartmentId = (select DepartmentId from inserted) where DepartmentId = (select DepartmentId from deleted) go
測試觸發器:
update Department set DepartmentId = 'zjb001' where DepartmentId='001'
我們會發現不但部門信息表中的部門編號進行了修改,員工信息表中部門編號為001的信息也被一起修改了。
存儲過程(Procedure)是SQL語句和流程控制語句的預編譯集合。
(1)沒有輸入參數,沒有輸出參數的存儲過程。
定義存儲過程實現查詢出賬戶余額最低的銀行卡賬戶信息,顯示銀行卡號,姓名,賬戶余額
--方案一 create proc proc_MinMoneyCard as select top 1 CardNo 銀行卡號,RealName 姓名,CardMoney 余額 from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId order by CardMoney asc go --方案二:(余額最低,有多個人則顯示結果是多個) create proc proc_MinMoneyCard as select CardNo 銀行卡號,RealName 姓名,CardMoney 余額 from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId where CardMoney=(select MIN(CardMoney) from BankCard) go
執行存儲過程:
exec proc_MinMoneyCard
(2)有輸入參數,沒有輸出參數的存儲過程
模擬銀行卡存錢操作,傳入銀行卡號,存錢金額,實現存錢操作
create proc proc_CunQian @CardNo varchar(30), @MoneyInBank money as update BankCard set CardMoney = CardMoney + @MoneyInBank where CardNo = @CardNo insert into CardExchange(CardNo,MoneyInBank,MoneyOutBank,ExchangeTime) values(@CardNo,@MoneyInBank,0,GETDATE()) --go
執行存儲過程:
exec proc_CunQian '6225125478544587',3000
(3)有輸入參數,沒有輸出參數,但是有返回值的存儲過程(返回值必須整數)。
模擬銀行卡取錢操作,傳入銀行卡號,取錢金額,實現取錢操作,取錢成功,返回1,取錢失敗返回-1
create proc proc_QuQian @CardNo varchar(30), @MoneyOutBank money as update BankCard set CardMoney = CardMoney - @MoneyOutBank where CardNo = @CardNo if @@ERROR <> 0 return -1 insert into CardExchange(CardNo,MoneyInBank,MoneyOutBank,ExchangeTime) values(@CardNo,0,@MoneyOutBank,GETDATE()) return 1 go
執行存儲過程:
declare @returnValue int exec @returnValue = proc_QuQian '662018092100000002',1000000 print @returnValue
(4)有輸入參數,有輸出參數的存儲過程
查詢出某時間段的銀行存取款信息以及存款總金額,取款總金額,傳入開始時間,結束時間,顯示存取款交易信息的同時,返回存款總金額,取款總金額。
create proc proc_SelectExchange @startTime varchar(20), --開始時間 @endTime varchar(20), --結束時間 @SumIn money output, --存款總金額 @SumOut money output --取款總金額 as select @SumIn = (select SUM(MoneyInBank) from CardExchange where ExchangeTime between @startTime+' 00:00:00' and @endTime+' 23:59:59') select @SumOut = (select SUM(MoneyOutBank) from CardExchange where ExchangeTime between @startTime+' 00:00:00' and @endTime+' 23:59:59') select * from CardExchange where ExchangeTime between @startTime+' 00:00:00' and @endTime+' 23:59:59' go
執行存儲過程:
declare @SumIn money --存款總金額 declare @SumOut money --取款總金額 exec proc_SelectExchange '2018-1-1','2018-12-31',@SumIn output,@SumOut output select @SumIn select @SumOut
(5)具有同時輸入輸出參數的存儲過程
密碼升級,傳入用戶名和密碼,如果用戶名密碼正確,并且密碼長度<8,自動升級成8位密碼
--有輸入輸出參數(密碼作為輸入參數也作為輸出參數) --密碼升級,傳入用戶名和密碼,如果用戶名密碼正確,并且密碼長度<8,自動升級成8位密碼 select FLOOR(RAND()*10) --0-9之間隨機數 create proc procPwdUpgrade @cardno nvarchar(20), @pwd nvarchar(20) output as if not exists(select * from BankCard where CardNo=@cardno and CardPwd=@pwd) set @pwd = '' else begin if len(@pwd) < 8 begin declare @len int = 8- len(@pwd) declare @i int = 1 while @i <= @len begin set @pwd = @pwd + cast(FLOOR(RAND()*10) as varchar(1)) set @i = @i+1 end update BankCard set CardPwd = @pwd where CardNo=@cardno end end go declare @pwd nvarchar(20) = '123456' exec procPwdUpgrade '6225547854125656',@pwd output select @pwd
感謝各位的閱讀,以上就是“SQL Server中函數、存儲過程與觸發器怎么用”的內容了,經過本文的學習后,相信大家對SQL Server中函數、存儲過程與觸發器怎么用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。