Home [SQL筆記] 函數二
Post
Cancel

[SQL筆記] 函數二

模擬銀行業務

函數的用意,通常情況下是可以重複使用的,如果僅僅為了這次(只用一次),工作量並沒有降低,如果很多時候都要用,就可以用函數。

範例1: case end 寫成函數

先查詢出來後,可以將兩個case end寫成兩個函數

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
--(4)查詢銀行卡信息,將銀行卡狀態1,2,3,4分別轉換為漢字"正常,掛失,凍結,註銷"
--根據銀行卡餘額顯示銀行卡等級30萬以下為"普通用戶",30萬以上為"VIP用戶"
--分別顯示卡號、身份証、姓名、餘額、用戶等級、銀行卡狀態
--Step1:先查詢出來
select BankCard.CardNo 卡號, AccountCode 身份証, RealName 姓名, CardMoney 餘額, 
case
    when CardMoney > 300000 then 'VIP用戶'
    else '普通用戶'
end 用戶等級,
case CardState
    when 1 then '正常'
    when 2 then '掛失'
    when 3 then '凍結'
    when 4 then '註銷'
    else '異常'
end 銀行卡狀態
from BankCard
inner join AccountInfo on BankCard.AccountId =  AccountInfo.AccountId

--Step2:兩個case end分別寫成兩個函數
--寫兩個函數
--(1)用戶等級函數
create function GetGrade(@cardmoney money) returns varchar(30)
as
begin
    declare @result varchar(30)
    if @cardmoney >= 300000
        set @result = 'VIP用戶'
    else
        set @result = '普通用戶'
    return @result --返回
end

--(2)求銀行卡狀態函數
create function GetState(@state int) returns varchar(30)
as
begin
    declare @result varchar(30)
    if @state = 1
        set @result = '正常'
    else if @state = 2
        set @result = '掛失'
    else if @state = 3
        set @result = '凍結' 
    else if @state = 4
        set @result = '註銷' 
    else 
        set @result = '異常'
    return @result
end

--Step3:把 step1 裡的 case-end 拿掉,換成函數
--select ...,用戶等級函數,銀行卡狀態函數 from BankCard inner join...
select BankCard.CardNo 卡號, AccountCode 身份証, RealName 姓名, CardMoney 餘額,
dbo.GetState(CardMoney) 用戶等級, dbo.GetGrade(CardState)
from BankCard
inner join AccountInfo on BankCard.AccountId =  AccountInfo.AccountId

範例2:計算實歲年齡(實歲函數)

建立測試資料

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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('Ken','男','2000-5-8'),
('Ben','男','1990-5-28'),
('UUU','男','2003-12-12'),
('DDD','男','2001-1-8'),
('FFF','男','2002-8-4'),
('VVV','男','1998-2-20'),
('PPP','男','1999-3-1'),
('OOO','男','1995-8-5')

實作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
--(5)編寫函數,根據出當日期求年齡,年齡求實歲,例如:
--生日 2000-5-5,當前為2018-5-4,年齡為17歲
--生日 2000-5-5,當前為2018-5-6,年齡為18歲

--第一個方案:(但沒判斷實歲)
select *, YEAR(GETDATE()) - YEAR(EmpBirth) 年齡 from Emp
--第二個方案:(判斷實歲)
--(1)寫一個函數判斷實歲
create function GetAge(@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
--(2)查詢調用函數
select *, dbo.GetAge(EmpBirth) 年齡 from Emp

--比較兩者差異
select *,YEAR(GETDATE()) - YEAR(EmpBirth) 年齡 from Emp
select *, dbo.GetAge(EmpBirth) 年齡 from Emp

https://www.bilibili.com/video/BV1XV411C7TP?p=28

This post is licensed under CC BY 4.0 by the author.