關系數據庫SQL之可編程性函數(用戶自定義函數)


前言

在關系型數據庫中除了前面幾篇基本的數據庫和數據表操作之外,還提供了可編程性的函數、存儲過程、事務、觸發器及游標。

本文介紹的是函數。

函數分為兩種:

  1. 系統函數
  2. 用戶自定義函數

准備工作

這里以銀行存取款為例說明。

1、創建數據表

--創建賬戶信息表
create table AccountInfo
(
	--賬戶ID
	CustID int identity(1,1) primary key,
	--帳戶名稱
	CustName varchar(20) not null,
	--身份證號
	IDCard varchar(18),
	--電話
	TelePhone varchar(13) not null,
	--地址
	Address varchar(50) default('地址不詳')
)

go

--創建卡信息表
create table CardInfo
(
	--銀行卡卡號
	CardID varchar(19) primary key,
	--銀行卡密碼
	CardPassWord varchar(6) not null default('888888'),
	--身份證號
	CustID int references AccountInfo(CustID),
	--存款類型
	SaveType varchar(10) not null ,
	--開戶日期
	OpenDate datetime not null default(getdate()),
	--開戶金額
	OpenMoney money not null check(OpenMoney>1),
	--可用余額
	LeftMoney money  not null check(LeftMoney>1),
	--是否掛失
	IsLost varchar(2) not null default('否')
)

go

--交易信息表
create table TransInfo
(
	--交易編號
	transID int identity primary key,
	--銀行卡卡號
	CardID varchar(19) not null,
	--交易類型
	TransType varchar(4) not null,
	--交易金額
	TransMoney money not null,
	--交易時間
	TransDate datetime default(getdate())
)
go

/*
1.使用T-SQL語句為交易信息表(TransInfo)的銀行卡卡號(CardID)字段創建外鍵
*/

--外鍵(銀行卡卡號CardID)
alter table [dbo].TransInfo  with check add  constraint [fk_CardInfo_TransInfo] foreign key(CardID)
references [dbo].[CardInfo] (CardID)
go

/*
2.使用T-SQL語句為賬戶信息表(AccountInfo)的銀行卡卡號(IDCard)字段創建唯一約束
*/
alter table [dbo].[AccountInfo] add unique (IDCard ASC)
go

/*
3.使用T-SQL語句創建約束,使銀行卡信息表(CardInfo)的銀行卡卡號(CardID)字段值長度只能為19位
*/
alter table [dbo].[CardInfo] add constraint CK_CardID check(len(CardID) = 19)
go

/*
4.使用T-SQL語句使交易信息表(TransInfo)的交易類型(TransType)字段只能選擇'存款'和'取款',
	銀行卡信息表(CardInfo)的存款類型(SaveType)字段只能選擇'定期'和'活期'
*/
alter table [dbo].TransInfo add constraint CK_TransType 
check(TransType = '存款' or TransType = '取款')
go
alter table [dbo].CardInfo add constraint CK_SaveType 
check(SaveType = '定期' or SaveType = '活期')
go

2、插入基本數據

--插入三個賬戶信息
insert into AccountInfo values
			('孫悟空','422322001502110017','027-88888888','花果山'),
			('唐僧','420322001902140019','027-85368962','大唐'),
			('沙和尚','410340001572144714','13295654665','通天河')
insert into CardInfo values
			('1027 3526 1536 1135','888888',1,'定期',default,500,500,'否'),
			('1029 3326 1536 1235','888888',2,'活期',default,1500,1500,'否'),
			('1324 3626 7532 1935','888888',1,'活期',default,4500,4500,'否')

函數調用

SELECT 字段列表/* FROM <函數名稱>([參數列表]);

系統函數

數據庫系統定義的函數,即內置函數。

函數列別 說明
聚合函數 執行的操作是將多個值合並為一個值。例如 COUNT、SUM、MIN 和MAX。
配置函數 是一種標量函數,可返回有關配置設置的信息。
加密函數 支持加密、解密、數字簽名和數字簽名驗證。
游標函數 返回有關游標狀態的信息。
日期和時間函數 可以更改日期和時間的值。
數學函數 執行三角、幾何和其他數字運算。
元數據函數 返回數據庫和數據庫對象的屬性信息。
排名函數 是一種非確定性函數,可以返回分區中每一行的排名值。
行集函數 返回可在 Transact-SQL 語句中表引用所在位置使用的行集。
安全函數 返回有關用戶和角色的信息。
字符串函數 可更改 char、varchar、nchar、nvarchar、binary 和 varbinary 的值。
系統函數 對系統級的各種選項和對象進行操作或報告。
系統統計函數 返回有關 SQL Server 性能的信息。
文本和圖像函數 可更改 text 和 image 的值。

具體的函數如果不清楚請自行搜索,本文着重介紹用戶自定義函數。


用戶自定義函數

除了系統提供的函數,用戶可以根據自己的需求自定義函數;
用戶自定義函數,顧名思義,就是數用戶自己定義的函數;
用戶自定義函數分為兩類:表值函數和標量值函數;
其中,表值函數也分兩種:內聯表值函數和多語句表值函數。


表值函數

表值函數是返回一個Table類型,相當與一張存儲在內存中的一張虛擬表。

內聯表值函數

語法

CREATE FUNCTION <函數名稱> 
(	
	-- 添加函數所需的參數,可以沒有參數
	[<@param1> <參數類型>]
	[,<@param1> <參數類型>]…
)
RETURNS TABLE 
AS
RETURN 
(
	-- 查詢返回的SQL語句
	SELECT查詢語句
)

示例

/*
* 創建內聯表值函數,查詢交易總額大於1W的開戶人個人信息
*/
create function getCustInfo()
returns @CustInfo table  --返回table類型
(
	--賬戶ID
	CustID int,
	--帳戶名稱
	CustName varchar(20) not null,
	--身份證號
	IDCard varchar(18),
	--電話
	TelePhone varchar(13) not null,
	--地址
	Address varchar(50) default('地址不詳')
)
as
begin
	--為table表賦值
	insert into @CustInfo
	select CustID,CustName,IDCard,TelePhone,Address from AccountInfo 
	where CustID in (select CustID from CardInfo 
	where CardID in (select CardID from TransInfo group by CardID,transID,TransType,TransMoney,TransDate having sum(TransMoney)>10000))
	return
end
go
-- 調用內聯表值函數
select * from getCustInfo()
go

多語句表值函數

語法

CREATE FUNCTION <函數名稱> 
(	
	-- 添加函數所需的參數,可以沒有參數
	[<@param1> <參數類型>]
	[,<@param1> <參數類型>]…
)
RETURNS 
<@定義的表名> TABLE 
(
	-- 添加返回數據表的列
	<列名1> <數據類型1>, 
	<列名2> <數據類型2>,
	……
	<列名n> <數據類型n>]
)
AS
BEGIN
	--為<@定義的表名>賦值的SQL語句
	RETURN 
END

示例

/*
* 創建多語句表值函數,可以查詢出一個月內有交易記錄的用戶姓名,聯系電話,身份證號碼,銀行卡卡號和賬戶余額
*/
create function getCustInfoMonth()
returns @CustInfo table  --返回table類型
(
	--帳戶名稱
	CustName varchar(20) not null,
	--電話
	TelePhone varchar(13) not null,
	--身份證號
	IDCard varchar(18),
	--銀行卡卡號
	CardID varchar(19) not null,
	--可用余額
	LeftMoney money  not null check(LeftMoney>1)
)
as
begin
	--為table表賦值
	insert into @CustInfo
		select A.CustName, A.TelePhone, A.IDCard, T.CardID, C.LeftMoney
		from AccountInfo as A inner join CardInfo as C on A.CustID = C.CustID 
		inner join TransInfo as T on C.CardID = T.CardID 
		where exists(select * from TransInfo 
		group by CardID,TransDate,transID,TransType,TransMoney
		having datediff(MONTH,TransDate,GETDATE())=0)
	return
end
go
-- 調用多語句表值函數
select * from getCustInfo()
go

標量值函數

返回一個標量值

語法

CREATE FUNCTION <FunctionName> 
(
	-- 添加函數所需的參數,可以沒有參數
	[<@param1> <參數類型>]
	[,<@param1> <參數類型>]…
)
RETURNS <函數返回數據類型>
AS
BEGIN
	-- 定義返回數據變量
	DECLARE @變量名 數據類型

	-- 通過SQL語句為返回變量賦值
	SELECT @變量名 = SQL語句

	-- 返回結果
	RETURN @變量名

END

示例

/*
7.創建標量值函數,根據用戶傳入的銀行卡卡號,獲得該卡交易次數
*/
create function getTransCount
(
	@CardID varchar(19)  --參數銀行卡卡號
)
returns int  --返回int類型
as
begin
	declare @count int
	select @count = count(*) from TransInfo where CardID = @CardID
	return @count
end
go
-- 調用標量值函數
select getTransCount('1027 3526 1536 1135') as 次數
go

函數部分介紹到這里,如有疑問,請留言。

謝謝各位看官的瀏覽。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM