根据用户定义函数返回值的类型,可将用户定义函数分为如下三个类别:

(1) 返回值为可更新表的函数

若用户定义函数包含单个 SELECT 语句且该语句可更新,则该函数返回的表也可更新,这样的函数称为内嵌表值函数。

(2) 返回不可更新数据表的函数

若用户定义函数包含多个 SELECT 语句,则该函数返回的表不可更新。这样的函数称为多语句表值函数。

(3) 返回标量值的函数

用户定义函数返回值为标量值,这样的函数称为标量函数。

用户定义函数不支持输出参数。用户定义函数不能修改全局数据库状态。

利用ALTER FUNCTION对用户定义函数修改,用 DROP FUNCTION 删除。

1.  标量函数

(1) 标量函数的定义

Format:

CREATE FUNCTION [ owner_name.] function_name      /*函数名部分*/

( [ { @parameter_name [AS] scalar_parameter_data_type [ = default ] }

[ ,...n ] ] )                                                               /*形参定义部分*/

RETURNS scalar_return_data_type                             /*返回参数的类型*/

[ WITH < function_option> [ [,] ...n] ]                          /*函数选项定义*/

[ AS ]

BEGIN

function_body                              /*函数体部分*/

RETURN scalar_expression                           /*返回语句*/

END

< function_option > ::={ ENCRYPTION | SCHEMABINDING }

说明:

SCHEMABINDING:用于指定将函数绑定到它所引用的数据库对象。

函数与其引用对象的绑定关系只有在发生以下两种情况之一时才被解除。

(1)删除了函数。

(2)在未指定 SCHEMABINDING 选项的情况下更改了函数。

从上述语法形式,归纳出标量函数的一般定义形式如下:

CREATE FUNCTION [所有者名.] 函数名

( 参数1 [AS] 类型1 [ = 默认值 ] ) [ ,...参数n [AS] 类型n [ = 默认值 ] ] ] )

RETURNS 返回值类型

[ WITH  ENCRYPTION |  SCHEMABINDING [ [,] ...n] ]

[ AS ]

BEGIN

函数体

RETURN 标量表达式

END

eg:

 /*计算全体学生某门功课的平均成绩*/
use XSCJ
create function average(@cnum char(20)) returns int
as
begin
declare @var int
select @var=
(
select AVG(Ccj)
from XS_KC
where Cno = @cnum
group by Cno
)
return @var
end
go

(2) 标量函数的调用

当调用用户定义的标量函数时,必须提供至少由两部分组成的名称(所有者名.函数名)。可有以下方式调用标量函数:

在SELECT语句中调用

调用形式:所有者名.函数名(实参1,…,实参n)

实参可为已赋值的局部变量或表达式。

eg1:

如下程序对上例定义的函数调用

 USE XSCJ        /*用户函数在此数据库中已定义*/
/* 定义局部变量 */
DECLARE @course1 char(6)
DECLARE @aver1 int
/* 给局部变量赋值 */
SELECT @course1 = ‘101’
/* 调用用户函数,并将返回值赋给局部变量 */
SELECT @aver1=dbo.average(@course1)
/* 显示局部变量的值 */
SELECT @aver1 AS ‘101课程的平均成绩’

Result:

利用EXEC语句执行

用T-SQL EXECUTE语句调用用户函数时,参数的标识次序与函数定义中的参数标识次序可以不同。

调用形式:

所有者名.函数名 实参1,…,实参n

所有者名.函数名 形参名1=实参1,…, 形参名n=实参n

eg2:

 【例6.36】调用上述计算平均成绩的函数。
USE XSCJ /* 用户函数在此数据库中已定义 */
DECLARE @aver1 int /* 显示局部变量的值 */
EXEC @aver1 = dbo.average @cnum = ‘101’
/*通过EXEC调用用户函数,并将返回值赋给局部变量*/
SELECT @aver1 AS ‘101课程的平均成绩’
GO

eg3:

 USE XSCJ  /*用户函数在此数据库中已定义*/
CREATE TABLE course
(
cno int, /*课程号*/
cname nchar(20), /*课程名*/
credit int, /*学分*/
aver AS /*将此列定义为计算列*/
(
dbo.average(cno)
)
)

Result:

2.  内嵌表值函数

内嵌函数可用于实现参数化视图。

eg:

 CREATE VIEW View1 AS
SELECT 学号, 姓名
FROM XSCJ.dbo.XS
WHERE 专业名= '计算机'

若希望设计更通用的程序,让用户能指定感兴趣的查询内容,可将WHERE 专业名= ‘计算机’替换为WHERE 专业名= @para, @para用于传递参数,但视图不支持在WHERE子句中指定搜索条件参数,为解决这一问题可使用内嵌用户定义函数。

eg:

 create function fn_view1 (@para char(10) = 'QW') returns table
as
return
(
select Sno,Sname
from XS
where Sdept = @para
)
go
select *from fn_view1(default)

Result:

  

(1) 内嵌表值函数的定义

Format:

CREATE FUNCTION [ owner_name.] function_name   /*定义函数名部分*/

( [ { @parameter_name [AS] scalar_parameter_data_type [ = default ] }

[ ,...n ] ] )                                 /*定义参数部分*/

RETURNS TABLE                          /*返回值为表类型*/

[ WITH < function_option > [ [,] ...n ] ]      /*定义函数的可选项*/

[ AS ]

RETURN [ ( ) select-stmt [ ] ]               /*通过SELECT语句返回内嵌表*/

< function_option > ::={ ENCRYPTION | SCHEMABINDING }

eg:

 /*对于XSCJ数据库,为了让学生每学期查询其各科成绩可以利用XS、KC、XS_KC三个表,创建视图*/
create view st_view
as
select XS.Sno,XS.Sname,KC.Cno,XS_KC.Ccj
from KC inner join
XS_KC on KC.Cno = XS_KC.Cno inner join
XS on XS_KC.Xno =XS.Sno
go

Result:

在上面创建的视图的基础上定义如下内嵌表值函数:

eg:

 /*在上面创建的视图的基础上定义如下内嵌表值函数*/
create function st_score(@student_id char(3)) returns table
as return
(
select *
from st_view
where st_view.Sno = @student_id
)
go

Result:

(2) 内嵌表值函数的调用

内嵌表值函数只能通过SELECT语句调用,内嵌表值函数调用时,可以仅使用函数名。

eg:

 /*调用st_score()函数,查询学号为“001”学生的各科成绩及学分。*/
select *
from XSCJ.dbo.st_score('')
go

Result:

3.多语句表值函数

内嵌表值函数和多语句都返回表,二者不同之处在于:内嵌表值函数没有函数主体,返回的表是单个SELECT语句的结果集;而多语句表值函数在 BEGIN...END 块中定义的函数主体包含T-SQL语句,这些语句可生成行并将行插入至表中,最后返回表。

(1) 多语句表值函数定义

Format:

CREATE FUNCTION [ owner_name.] function_name          /*定义函数名部分*/

( [ { @parameter_name [AS] scalar_parameter_data_type [ = default ] }

[ ,...n ] ] )                                                                                       /*定义函数参数部分*/

RETURNS @return_variable TABLE < table_type_definition > /*定义作为返回值的表*

[ WITH < function_option > [ [,] ...n ] ]                         /*定义函数的可选项*/

[ AS ]

BEGIN

function_body                                                               /*定义函数体*/

RETURN

END

< function_option > ::={ ENCRYPTION | SCHEMABINDING }

< table_type_definition > ::=                                 /*定义表,请参考第二章*/

( { column_definition | table_constraint } [ ,...n ] )

@return_variable:为表变量,用于存储作为函数值返回的记录集;

function_body:为T-SQL语句序列,function_body只用于标量函数和多语句表值函数。

eg:

 /*在XSCJ数据库中创建返回table的函数,通过以学号作为实参,调用该函数,可显示该学生各门功课的成绩和学分*/
create function score_table (@st_id char(3)) returns @score table
(
student_id char(3),
Student_name char(8),
kc_name char(12),
student_ci tinyint,
student_sf tinyint
)
as
begin
insert @score
select XS.Sno,Sname,Cname,Ccj,Cfen
from XS join XS_KC join KC on XS_KC.Cno =KC.Cno on XS.Sno=XS_KC.Xno
where XS.Sno=@st_id
return
end
go

Result:

(2) 多语句表值函数的调用

多语句表值函数的调用与内嵌表值函数的调用方法相同。如下例子是上述多语句表值函数score_table()的调用。

eg:

 /*如下语句查询学号为”005”学生的各科成绩和学分。*/
use XSCJ
select *from score_table('')
go
/*结果怎么什么都没有?我不明白。*/

Result:

图片1

4.用户函数的建立

用户函数的建立可利用查询分析器完成,也可利用企业管理器完成。

(1) 利用查询分析器创建用户定义函数

例如在XSCJ数据库中要建立前面求立方体体积的用户函数,可在查询分析器窗口输入例中的程序并执行,然后在查询分析器的目录树上XSCJ数据库对应的函数子目录图标上右击,选择“刷新”,即可看到函数SphereVolume()对象的图标。

定义用户函数SphereVolume()后,在查询分析器中即可调用该函数。

(2) 利用企业管理器创建用户定义函数

5.用户定义函数的删除

对于一个已创建的用户定义函数,可有两种方法删除:

通过企业管理器删除,这非常简单,请读者自己练习;

利用T-SQL语句DROP FUNCTION删除,下面介绍其语法格式。

语法格式:DROP FUNCTION { [ owner_name .] function_name } [ ,...n ]

说明:

owner_name:指所有者名。

function_name:指要删除的用户定义的函数名称。可以选择是否指定所有者名称,但不能指定服务器名称和数据库名称。

n:表示可以指定多个用户定义的函数予以删除。

SqlServer——用户定义函数的更多相关文章

  1. 应用C#和SQLCLR编写SQL Server用户定义函数

    摘要: 文档阐述使用C#和SQLCLR为SQL Server编写用户定义函数,并演示用户定义函数在T-SQL中的应用.文档中实现的 Base64 编码解码函数和正则表达式函数属于标量值函数,字符串分割 ...

  2. SQL Server 2019 中标量用户定义函数性能的改进

    在SQL Server中,我们通常使用用户定义的函数来编写SQL查询.UDF接受参数并将结果作为输出返回.我们可以在编程代码中使用这些UDF,并且可以快速编写查询.我们可以独立于任何其他编程代码来修改 ...

  3. SQL——用户定义函数

    根据用户定义函数返回值的类型,可将用户定义函数分为如下三个类别: (1) 返回值为可更新表的函数 若用户定义函数包含单个 SELECT 语句且该语句可更新,则该函数返回的表也可更新,这样的函数称为内嵌 ...

  4. SQL 中用户定义函数的使用方法

    --用户定义函数的分类: /* 1.标量函数 2.表值函数 2.1内联表值函数  返回单个SELECT语句, 它没有相关的返回变量和函数体 2.2多语句表值函数  是视图和存储过程的结合 可嵌套 */ ...

  5. Linux Shell管道调用用户定义函数(使shell支持map函数式特性)

    Linux中有一个管道的概念,常用来流式的处理文本内容,比如一个文件对其中的每一行应用好几个操作,出于两个方面的考虑可能需要在管道中使用用户定义函数: 1. 刚需: 内置的sed/awk之类的可能没法 ...

  6. 调试SQL Server的存储过程及用户定义函数

    分类: 数据库管理 2005-06-03 13:57 9837人阅读 评论(5) 收藏 举报 sql server存储vb.net服务器sql语言 1.在查询分析器中调试 查询分析器中调试的步骤如下: ...

  7. Hadoop Hive概念学习系列之hive里的用户定义函数UDF(十七)

    Hive可以通过实现用户定义函数(User-Defined Functions,UDF)进行扩展(事实上,大多数Hive功能都是通过扩展UDF实现的).想要开发UDF程序,需要继承org.apache ...

  8. 【翻译】Flink Table Api & SQL — 用户定义函数

    本文翻译自官网:User-defined Functions  https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/tabl ...

  9. sqlserver 用户定义表类型

    有时需要将内存中的表与数据库中的表比较,比如Datatable中有100行数据,需要判断在数据库中是否存在,这个时候我们就可以使用sqlserver中的[用户 定义表类型] 这里最最最重要的思路是把[ ...

随机推荐

  1. kali视频(16-20)学习

    第五周 kali视频(16-20)学习 16.漏洞分析之数据库评估(一) 17.漏洞分析之数据库评估(二) 18.漏洞分析之WEB应用代理 19.漏洞分析之burpsuite 20.漏洞分析之fuzz ...

  2. pmm监控页面502

    我们知道pmm主要使用的是 普罗米修斯采集和grafana日志统计显示. 最近为硬盘扩过一次容量,主要是docker使用的,我的pmm是跑在docker上的,但是重启后pmm的debug日志下载502 ...

  3. 一线互联网公司必备——最为详细的Docker入门吐血总结

    在计算机技术日新月异的今天, Docker 在国内发展的如火如荼.     特别是在一线互联网公司 Docker 的使用是十分普遍的,甚至成为了一些企业面试的加分项,不信的话看看下面这张图.     ...

  4. ORA-28595: Extproc 代理: DLL 路径无效解决办法

    报错信息: ORA-28595: Extproc 代理: DLL 路径无效 ORA-06512: 在 "SDE.ST_GEOMETRY_SHAPELIB_PKG", line 70 ...

  5. retful上传文件php的实现

    项目中要使用restful上传文件到服务器,一直不能成功,后生成相关串后在postman中上传成功,利用这个工具生成php curl的代码,后逐步比对产生以下代码. /**     * 上传文件    ...

  6. python开发进程:进程开启方式&多进程

    一,进程的开启方式 利用模块开启进程 from multiprocessing import Process import time,random import os def piao(name): ...

  7. C++11 变量和函数的链接性

    在全局变量前添加const或者static,则该变量链接性为内部,即文件内有效.可以使用extern声明为外部. 如果要让函数的链接性为内部,则函数声明和定义都应使用static关键字. 例子: te ...

  8. 众包高效实用的.NET开源项目

    1.Akka.NET: 概述:更轻松地构建强大的并发和分布式应用. 简介:Akka.NET是一个用于在.NET和Mono上构建高度并发,分布式和容错的事件驱动应用程序的工具包和运行时. 开源地址:ht ...

  9. HTTP 与TCP/IP 、Socket区别(一)

    网络由下往上分为: 物理层-- 数据链路层-- 网络层-- IP协议 传输层-- TCP协议 会话层-- 表示层和应用层-- HTTP协议 1.TCP/IP连接 手机能够使用联网功能是因为手机底层实现 ...

  10. DEV CheckComboboxEdit、CheckedListBoxControl(转)

    CheckComboboxEdit //先清空所有,若在窗体Load事件中,也可以不清空 //cbRWYs.Properties.Items.Clear(); var RwyList = tspro. ...