SQLServer用户自定义函数详细介绍
SQLSERVER-自定义函数

SQLSERVER-⾃定义函数⽬录产⽣背景(已经有了存储过程,为什么还要使⽤⾃定义函数)发展历史构成使⽤⽅法适⽤范围注意事项疑问内容产⽣背景(已经有了存储过程,为什么还要使⽤⾃定义函数)与存储过程的区别(存在的意义):1. 能够在select等SQL语句中直接使⽤⾃定义函数,存储过程不⾏。
2. ⾃定义函数可以调⽤其他函数,也可以调⽤⾃⼰(递归)3. 可以在表列和 CHECK 约束中使⽤⾃定义函数来实现特殊列或约束4. ⾃定义函数不能有任何副作⽤。
函数副作⽤是指对具有函数外作⽤域(例如数据库表的修改)的资源状态的任何永久性更改。
函数中的语句唯⼀能做的更改是对函数上的局部对象(如局部游标或局部变量)的更改。
不能在函数中执⾏的操作包括:对数据库表的修改,对不在函数上的局部游标进⾏操作,发送电⼦邮件,尝试修改⽬录,以及⽣成返回⾄⽤户的结果集。
存储过程没有此限制5. 函数只能返回⼀个变量。
⽽存储过程可以返回多个发展历史SqlServer 2000之后都⽀持⽤户⾃定义函数构成在SQL Server 2000 中根据函数返回值形式的不同将⽤户⾃定义函数分为三种类型:标量函数(Scalar Function)、内嵌表值函数(Inline Function)、多声明表值函数(Multi-Statement Function)标量函数:标量函数是对单⼀值操作,返回单⼀值。
能够使⽤表达式的地⽅,就可以使⽤标量函数。
像我们经常使⽤的left、getdate等,都属于标量函数。
系统函数中的标量函数包括:数学函数、⽇期和时间函数、字符串函数、数据类型转换函数等内嵌表值函数:内嵌表值函数的功能相当于⼀个参数化的视图。
它返回的是⼀个表,内联表值型函数没有由BEGIN-END 语句括起来的函数体。
其返回的表由⼀个位于RETURN ⼦句中的SELECT 命令段从数据库中筛选出来。
作⽤多声明表值函数:可以看作标量型和内嵌表值型函数的结合体。
SQLServerCLR使用C#自定义函数

SQLServerCLR使⽤C#⾃定义函数⼀、简介Microsoft SQL Server 2005之后,实现了对 Microsoft .NET Framework 的公共语⾔运⾏时(CLR)的集成。
CLR 集成使得现在可以使⽤ .NET Framework 语⾔编写代码,从⽽能够在 SQL Server 上运⾏,现在就可以通过 C# 来编写 SQL Server ⾃定义函数、存储过程、触发器等。
我最初的⽬的是因为在 SQL Server 数据库中遇到数字的⼗进制与⼗六进制的互相转换问题,也看过⼀些⽅法吧,但是最后我却选择了⽤CLR 来做,毕竟在 C# 中两三⾏代码就能搞定的问题。
⼆、配置 SQL Server CLR开启 CLR:--开启所有服务器配置sp_configure 'show advanced options', 1;RECONFIGURE WITH overrideGO--开启 CLRsp_configure 'clr enabled', 1;RECONFIGURE WITH overrideGO关闭 CLR:--关闭所有服务器配置sp_configure 'show advanced options', 0;RECONFIGURE WITH overrideGO--关闭 CLRsp_configure 'clr enabled', 0;RECONFIGURE WITH overrideGO在后⾯注册 CLR 程序集时,发⽣因操作权限问题⽽导致的失败时,可以尝试执⾏下⾯的 SQL 语句,这⾥我把 SQL ⼀并贴出来。
--权限不够时,设置⽬标数据库为可信赖的,例如:TestALTER DATABASE[Test]SET TRUSTWORTHY ON--修改数据库所有者为当前登录的⽤户,也可以为其他⽤户,例如:saEXEC sp_changedbowner 'sa'三、CLR Function打开 Visual Studio 新建⼀个 SQL Server 数据库项⽬,这⾥需要注意 .NET Framework 的版本。
SQLserver自定义函数FUNCTION的使用

SQLserver⾃定义函数FUNCTION的使⽤⼀.标量值函数、内联表值函数、多语句表值函数举例说明1、标量值函数(返回⼀个标量值)CREATE FUNCTION dbo.func_date_get_name(@date_into varchar(8))--CREATE FUNCTION 函数名称(@参数名参数的数据类型)RETURNS varchar(20) --返回返回值的数据类型--[WITH ENCRYPTION] --如果指定了 encryption 则函数被加密asBEGINdeclare@result_name varchar(20)select@result_name= Value_name from test_ceshi where statdate =@date_intoRETURN@result_nameEND--select dbo.func_date_get_name('20180808') name;--select * from test_ceshi;2、内联表格值函数定义格式:特点:内联表格值函数⽀持在WHERE⼦句中使⽤参数CREATE FUNCTION dbo.func_date_get_table(@date_into varchar(8))RETURNS table--[WITH ENCRYPTION] --如果指定了 encryption 则函数被加密asRETURN select statdate,Value_name from test_ceshi where statdate =@date_into--select * from dbo.func_date_get_table('20180808') ;3、多语句表值函数定义格式:多语句表值函数跟内联表值函数都是表值函数,它们返回的结果都是Table类型。
多语句表值函数通过多条语句来创建Table类型的数据。
SQLServer自定义字符串处理函数

SQLServer⾃定义字符串处理函数1.字符串分割函数ALTER function [dbo].[split](@c varchar(2000),@split varchar(2))returns @t table(col varchar(20))asbeginwhile(charindex(@split,@c)<>0)begininsert @t(col) values (substring(@c,1,charindex(@split,@c)-1))set @c = stuff(@c,1,charindex(@split,@c),'')endinsert @t(col) values (@c)returnend试⼀试: select * from split('1,2,3',',')2.字符串数组长度ALTER function [dbo].[fnGetStrArrayLength](@str varchar(8000), --要分割的字符串@split varchar(10) --分隔符号)returns intasbegindeclare @location intdeclare @start intdeclare @length intset @str=ltrim(rtrim(@str))set @location=charindex(@split,@str)set @length=1while @location<>0beginset @start=@location+1set @location=charindex(@split,@str,@start)set @length=@length+1endreturn @lengthend试⼀试:declare @length intset @length=dbo.fnGetStrArrayLength('1,2,3',',')select @length3.获取字符串数组某个元素的值ALTER function [dbo].[fnGetStrArrayValue](@str varchar(8000), --要分割的字符串@split varchar(10), --分隔符号@index int --取第⼏个元素)returns varchar(1024)asbegindeclare @location intdeclare @start intdeclare @next intdeclare @seed intset @str=ltrim(rtrim(@str))set @start=1set @next=1set @seed=len(@split)set @location=charindex(@split,@str)while @location<>0 and @index>@nextbeginset @start=@location+@seedset @location=charindex(@split,@str,@start)set @next=@next+1endif @location =0 select @location =len(@str)+1--这⼉存在两种情况:1、字符串不存在分隔符号 2、字符串中存在分隔符号,跳出while循环后,@location为0,那默认为字符串后边有⼀个分隔符号。
T-SQL编程——用户自定义函数(标量函数)

T-SQL编程——⽤户⾃定义函数(标量函数)⽤户⾃定义函数 在使⽤SQL server的时候,除了其内置的函数之外,还允许⽤户根据需要⾃⼰定义函数。
根据⽤户定义函数返回值的类型,可以将⽤户定义的函数分为三个类别:返回值为可更新表的函数 如果⽤户定义函数包含了单个select语句且语句可更新,则该函数返回的表也可更新,这样的函数称为内嵌表值函数。
返回值不可更新表的函数 如果⽤户定义函数包含多个select语句,则该函数返回的表不可更新。
这样的函数称为多语句表值函数。
返回标量值的函数 ⽤户定义函数返回值为标量值,这样的函数称为标量函数。
在这⾥需要说明⼀下,⽤户定义的函数是可以接受零个或多个输⼊参数的,函数的返回值可以是⼀个数值,也可以是⼀个表。
⽤户定义的函数不⽀持输出函数; 利⽤alter function可以对⽤户定义函数进⾏修改,⽤drop function 可以删除⽤户定义函数(当然,也可以直接通过图形界⾯操作进⾏删除,但这⾥不多累述);标量函数的定义与调⽤ 标量函数定义的语法格式如下: 1create function[owner_name] function_name2 ([{@parameter_name [as] scalar_parameter_date_type [=default]}[,…n]])3returns scalar_return_data_type [with encryption][as]4begin5 function_body6return scalar_expression7end 其中的含义分别如下:owner_name : 数据库所有名。
function_name:⽤户定义函数名,函数名必须符合标⽰符规范,对其所有者来说,该⽤户名在数据库中必须是唯⼀的。
@parameter_name:⽤户定义函数的形参名, create function 语句中可以申明⼀个或多个参数,⽤@符号作为第⼀个字符来指定形参名,每个函数的参数局部作⽤于该函数。
CREATE FUNCTION sqlserver用户定义函数

创建用户定义函数,它是返回值的已保存的Transact-SQL 例程。
用户定义函数不能用于执行一组修改全局数据库状态的操作。
与系统函数一样,用户定义函数可以从查询中唤醒调用。
也可以像存储过程一样,通过EXECUTE 语句执行创建用户定义函数,它是返回值的已保存的 Transact-SQL 例程。
用户定义函数不能用于执行一组修改全局数据库状态的操作。
与系统函数一样,用户定义函数可以从查询中唤醒调用。
也可以像存储过程一样,通过 EXECUTE 语句执行。
用户定义函数用 ALTER FUNCTION 修改,用 DROP FUNCTION 除去。
语法标量函数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 ]BEGINfunction_bodyRETURN scalar_expressionEND内嵌表值函数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 [ ) ]多语句表值函数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 ]BEGINfunction_bodyRETURNEND< function_option > ::={ ENCRYPTION | SCHEMABINDING }< table_type_definition > ::=( { column_definition | table_constraint } [ ,...n ] )参数owner_name拥有该用户定义函数的用户 ID 的名称。
SQL自定义函数

SQL函数 SQL函数
系统函数 —标量函数 标量函数
系统函数 标量函数 聚合函数 行集函数。 行集函数。 标量函数 标量函数对单一值操作,返回单一值。 标量函பைடு நூலகம்对单一值操作,返回单一值。只要在能够使用表达式的 地方,就可以使用标量函数。 地方,就可以使用标量函数。 数学函数 日期和时间函数 字符串函数 数据类型转换函数 。
SQL函数 SQL函数
系统函数—标量函数 标量函数
数学函数 5、 rand(整型表达式 整型表达式) 、 整型表达式 功能:返回一个位于0和 之间的随机数 之间的随机数, 功能:返回一个位于 和1之间的随机数,在单个查询中反复调用 rand( )将产生相同的值。 将产生相同的值。 将产生相同的值 例:DECLARE @counter smallint SET @counter = 1 WHILE @counter < 5 BEGIN SELECT RAND(@counter) Random_Number SET NOCOUNT ON SET @counter = @counter + 1 SET NOCOUNT OFF END GO
SQL函数 SQL函数
系统函数—标量函数 标量函数
数学函数 1、abs(数值型表达式 数值型表达式) 、 数值型表达式 功能: 的绝对值,其值的数据类型与参数一致。 功能:返回表达式 的绝对值,其值的数据类型与参数一致。 例:SELECT ABS(-1), ABS(0), ABS(1) 2、ceiling(数值型表达式 数值型表达式) 、 数值型表达式 功能:返回最小的大于或等于给定数值型表达式的整数值, 功能:返回最小的大于或等于给定数值型表达式的整数值,值的 类型和给定的值相同。 类型和给定的值相同。 floor(数值型表达式 数值型表达式) 数值型表达式 功能:返回最大的小于或等于给定数值型表达式的整数值。 功能:返回最大的小于或等于给定数值型表达式的整数值。 例:SELECT FLOOR(123.45),CEILING(123.45) SELECT FLOOR(-123.45), CEILING(-123.45)
实验八(上):SQL-Server用户自定义函数和触发器

实验八(上)用户自定义函数和触发器一、实验目的1、掌握SQLServer中用户自定义函数的使用方法。
2、掌握SQL Server中触发器的使用方法。
二、实验内容和要求1.创建一个返回标量值的用户定义函数RectangleArea:输入矩形的长和宽就能计算矩形的面积。
自选2种实例调用该函数。
create function RectangleArea(@a int,@b int)returns intasbeginreturn @a*@benddeclare @area intexecute @area=RectangleArea 3,5print('矩形面积是:')print @areadeclare @area intexecute @area=RectangleArea 7,8print('矩形面积是:')print @area2.创建一个用户自定义函数(内嵌表值函数),功能为产生某个系的学生选修信息,内容为学号,姓名,课程名,成绩。
调用这个函数,显示信息系有选课学生的信息。
create function Search (@sdept char(10))returns tableasreturn(select sc.sno 学号,student.sname 姓名,ame 课程名,sc.grade 成绩,student.sdept 系别from sc,student,course where o=o andsc.sno = student.sno and sdept=@sdept)select*from Search('cs')3.创建一个作用在P表上的触发器P_checks,确保用户在插入或更新P表的WEIGHT值时,所提供的WEIGHT值介于20与40之间,否则给出错误提示并回滚此操作。
请测试该触发器,测试方法自定。
create trigger P_checks on p for insertasbegindeclare @weight intselect @weight=weight from insertedif @weight<10 or @weight>20beginRAISERROR('weight 必须在~20之间!',16,1)ROLLBACK TRANSACTIONendendinsert into p(pno,pname,color,weight)values('p7','刀片','红',40)insert into p(pno,pname,color,weight)values('p7','刀片','红',15)select*from p4.创建一个作用在J表上的触发器J_Update,禁止同时修改项目的名称和所在城市,并进行相应的错误提示。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
SQL Server用户自定义函数
用户自定义函数不能用于执行一系列改变数据库状态的操作,但它可以像系统函数一样在查询或存储过程等的程序段中使用,也可以像存储过程一样通过EXECUTE 命令来执行。
在 SQL Server 中根据函数返回值形式的不同将用户自定义函数分为三种类型:
(1) 标量函数
标量函数返回一个确定类型的标量值,其返回值类型为除 TEXT 、 NTEXT 、IMAGE 、 CURSOR 、 TIMESTAMP 和 TABLE 类型外的其它数据类型。
函数体语句定义
在 BEGIN-END 语句内。
在 RETURNS 子句中定义返回值的数据类型,并且函数的最后一条语句必须为 Return 语句。
创建标量函数的格式:
Create Function 函数名(参数)
Returns 返回值数据类型
[With {Encryption|Schemabinding}]
[AS]
BEGIN
SQL 语句 ( 必须有 Return 子句 )
END
举例:
******************************************************************* CREATE FUNCTION dbo.Max
(
@a int,
@b int
)
RETURNS int AS
BEGIN
DECLARE @max int
IF @a>@b SET @max=@a
ELSE SET @max=@b
Return @max
END
*******************************************************************调用标量函数可以在 T-SQL 语句中允许使用标量表达式的任何位置调用返
回标量值(与标量表达式的数据类型相同)的任何函数。
必须使用至少由两部分组成名称的函数来调用标量值函数,即架构名 . 对象名,如 dbo.Max(12,34) 。
(2) 内联表值函数
内联表值型函数以表的形式返回一个返回值,即它返回的是一个表。
内联表
值型函数没有由 BEGIN-END 语句括起来的函数体。
其返回的表是由一个位于RETURN 子句中的 SELECT 命令从数据库中筛选出来。
内联表值型函数功能相当
于一个参数化的视图。
******************************************************************* Create Function 函数名(参数)
RETURNS table
[with {Encryption|Schemabinding}]
AS
Return( 一条 SQL 语句 )
举例:
CREATE FUNCTION func (@id char(8))
RETURNS TABLE
AS
RETURN (SELECT * FROM student WHERE SID = @id)
*********************************************************************
调用内联表值函数:调用时不需指定架构名,如 select * from
func('51300521')
(3) 多语句表值函数
多语句表值函数可以看作标量函数和内联表值函数的结合体。
它的返回值是
一个表,但它和标量型函数一样有一个用 BEGIN-END 语句括起来的函数体,返
回值的表中的数据是由函数体中的语句插入的。
由此可见,它可以进行多次查询,对数据进行多次筛选与合并,弥补了内联表值函数的不足。
Create Function 函数名(参数)
RETURNS 表变量名 ( 表变量字段定义 )[with {Encryption|Schemabinding}]
AS
BEGIN
SQL 语句
Return
END
举例:
******************************************************************* CREATE FUNCTION func(@selection int)
RETURNS @table TABLE
(
SID char(4) primary key not null,
SName nvarchar(4) null
)
AS
BEGIN
IF @selection = 0
INSERT INTO @table (SELECT SID,SName FROM student0)
ELSE
INSERT INTO @table (SELECT SID,SName FROM student1)
Return
END
*******************************************************************
调用多语句表值函数:和调用内联表值函数一样,调用时不需制定架构名。
注意:与编程语言中的函数不同的是, SQL Server 自定义函数必须具有返
回值。
注意: Schemabinding 用于将函数绑定到它引用的对象上。
函数一旦绑定,
则不能删除、修改,除非删除绑定。
一个完整的简单例子:
--创建函数
if exists(select 1 from sysobjects where id=object_id('GetMax') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[GetMax] --如果在系统中存在该函数,则删除
create function GetMax(@x int,@y int)
returns int
--with encryption --加上这句表示加密
as
begin
declare @t int
if(@x>@y)
set @t=@x
else
set @t=@y
return @t
end
go
select dbo.GetMax(6.9,3.3) --调用时不是直接GetMax 而是dbo.GetMax
sp_helptext getmax --查看该函数的详细信息(加密后无法查看)
drop function dbo.getmax --删除该函数
注意事项:
用户自定义函数不能用于执行一系列改变数据库状态的操作
在编写自定义函数时需要注意的:
对于标量函数:
1.所有的入参前都必须加@
2.create后的返回,单词是returns,而不是return
3.returns后面的跟的不是变量,而是返回值的类型,如:int,char等。
4.在begin/end语句块中,是return。
内嵌表值函数:
1.只能返回table,所以returns后面一定是TABLE
2.AS后没有begin/end,只有一个return语句来返回特定的记录。
多语句表值函数:
1.returns后面直接定义返回的表类型,首先是定义表名,表明前面要加@,然后是关键字
TABLE,最后是表的结构。
2.在begin/end语句块中,直接将需要返回的结果insert到returns定义的表中就可以了,
在最后return时,会将结果返回。
3.最后只需要return,return后面不跟任何变量。
疑问:自定义函数不能修改数据库,但它可以调用存储过程,那么在自定义函数中调用一个有修改数据库的操作的存储过程,这个自定义函数能不能执行?
答:自定义函数只能调用扩展存储过程,但是SQL Server 2008的后续版本将删除该功能,不再支持扩展存储过程,所以应避免在开发中使用扩展存储过程。
因此,可以得出结论是:实际开发中,函数不会去调用存储过程,也就无法对数据库进行修改操作了。
以上内容来自百度,在此基础上加以整理。