函数

自定义函数

1.用户自定义函数与存储过程的比较

| 比较项 |用户自定义函数 |存储过程|
|:------:|:-----:-| :-----:-|
|参数|允许有0到多个输入参数,不允许有输出参数|允许有多个输入/输出参数|
|返回值|有且只有一个返回值|可以没有返回值|
| 调用|在表达式或赋值语句中引用|使用EXECUTE调用|
|其他|可以返回表变量,但不能使用OUTPUT参数,不能使用临时表,不能通过select返回结果集|不能返回表变量|

2.自定义函数分类
  根据函数返回值的不同,自定义函数可分为标量值函数和表值函数。具体如下。
(1)标量值函数
  标量值函数的返回值是返回子句(RETURNS子句)中定义的类型的单个数据值,不能返回多个值。
(2)内嵌表值函数
  内嵌表值函数返回的是在RETURNS子句中指定的“table”类型的数据行集(表)。在内嵌表值函数中,RETURNS子句在括号中含有一条单独的SELECT查询语句,该语句的结果构成了内嵌表值函数所返回的表。
  内嵌表值函数可以替代视图,并且比视图的逻辑功能更强大。在T-SQL查询中允许使用表或视图表达式的地方,也可以使用内嵌表值函数。
  内嵌表值函数还可以替代返回单个结果集的存储过程。内嵌表值函数返回的表可在T-SQL语句的FROM子句中被引用,而存储过程返回的结果集不能被引用。
(3)多语句表值函数
  与内嵌表值函数一样,多语句表值函数返回的是由选择结果构成的数据行集(表)。与内嵌表值函数不同的是,多语句表值函数在返回语句之前还有其他的T-SQL语句,并且RETURNS子句指定的表带有列及其他数据类型。

创建自定义函数

(1)创建标量值函数

CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   
( [ { @parameter_name [ AS ][ type_schema_name. ] parameter_data_type   
    [ = default ] [ READONLY ] }   
    [ ,...n ]  
  ]  
)  
RETURNS return_data_type  
    [ WITH <function_option> [ ,...n ] ]  
    [ AS ]  
    BEGIN   
        function_body   
        RETURN scalar_expression  
    END  

<function_option>::=   
{  
    [ ENCRYPTION ]  
  | [ SCHEMABINDING ]  
  | [ RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT ]  
  | [ EXECUTE_AS_Clause ]  
}  
  • 返回类型不能是text、ntext、image、cursor、timestamp和表类型;
  • READONLY:指示不能在函数定义中更新或修改参数。 如果参数类型为用户定义的表类型,则应指定 READONLY。
  • return_data_type:标量用户定义函数的返回值。
  • scalar_expression:指定标量函数返回的标量值。
  • 在BEGIN...END之间的语句是函数体,函数体中国必须包含一条不带参数的RETURN语句用于返回表。

【示例】

CREATE FUNCTION EProduct_Number
(@EP_CID int)
RETURNS smallint
AS
BEGIN
  DECLARE @epnum smallint
  SELECT @epnum = count(*) FROM EProduct WHERE CID=@EP_CID
  RETURN @epnum
END
GO 

(2)创建内联表值函数

CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   
( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type   
    [ = default ] [ READONLY ] }   
    [ ,...n ]  
  ]  
)  
RETURNS TABLE  
    [ WITH <function_option> [ ,...n ] ]  
    [ AS ]  
    RETURN [ ( ] select_stmt [ ) ]  
  • 内联表值函数没有函数体。
  • TABLE:指定表值函数的返回值为表。
  • 在内联表值函数中,TABLE 返回值是通过单个 SELECT 语句定义的。 内联函数没有关联的返回变量。

【示例】

CREATE FUNCTION EProduct_Table
(@EP_CID int)
RETURNS Table
AS
   RETURN(SELECT ENO,EName FROM EProduct WHERE cid=@EP_CID)

若要调用该函数,请运行此查询:

SELECT * FROM  EProduct_Table(1)

(3)多语句表值函数

与内联表值函数不同的是,多语句表值函数在返回语句之前还有其他的T-SQL语句,具体的语法格式如下:

CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   
( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type   
    [ = default ] [READONLY] }   
    [ ,...n ]  
  ]  
)  
RETURNS @return_variable TABLE <table_type_definition>  
    [ WITH <function_option> [ ,...n ] ]  
    [ AS ]  
    BEGIN   
        function_body   
        RETURN  
    END  

<table_type_definition>:: =   
( { <column_definition> <column_constraint>   
  | <computed_column_definition> }   
    [ <table_constraint> ] [ ,...n ]  
)   
  • 在多语句表值函数中,@return_variable是表变量,用于存储和累积应作为函数的值返回的行。该变量的数据类型是Table,而且在该子句中还需要对返回的表进行表结构的定义。
  • 在BEGIN...END之间的语句是函数体,函数体中国必须包含一条不带参数的RETURN语句用于返回表。

【示例】

CREATE FUNCTION EProduct_Table_1
(@EP_CID int)
RETURNS @tb Table
(
  tb_Eno char(11),
  tb_EName varchar(50),
  tb_EJoinData DateTime
)
AS
BEGIN
  INSERT INTO @tb SEELCT ENO,EName,EJoinDate FROM EProduct WHERE CID = @EP_CID
  RETURN
END

限制和局限

①用户定义函数不能用于执行修改数据库状态的操作。
②用户定义函数不能包含将表作为其目标的 OUTPUT INTO 子句。

函数的管理

①删除函数

DROP FUNCTION [ IF EXISTS ] { [ schema_name. ] function_name } [ ,...n ]   
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容