sql server 函数的自定义

 

建立用户定义函数。这是一个已保存 Transact-SQL 或公共语言运行时 (CLR) 例程,该例程可返回一个值。用户定义函数不能用于执行修改数据库状态的操做。与系统函数同样,用户定义函数可从查询中调用。标量函数和存储过程同样,可以使用 EXECUTE 语句执行。html

用户定义函数可以使用 ALTER FUNCTION 修改,使用 DROP FUNCTION 删除。sql

主题连接图标 Transact-SQL 语法约定数据库

语法


Scalar Functions CREATE FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ][ type_schema_name. ] parameter_data_type     [ = default ] }     [ ,...n ]   ] ) RETURNS return_data_type     [ WITH <function_option> [ ,...n ] ]     [ AS ]     BEGIN                 function_body         RETURN scalar_expression     END [ ; ] Inline Table-valued Functions CREATE FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type     [ = default ] }     [ ,...n ]   ] ) RETURNS TABLE     [ WITH <function_option> [ ,...n ] ]     [ AS ]     RETURN [ ( ] select_stmt [ ) ] [ ; ] Multistatement Table-valued Functions CREATE FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type     [ = default ] }     [ ,...n ]   ] ) RETURNS @return_variable TABLE < table_type_definition >     [ WITH <function_option> [ ,...n ] ]     [ AS ]     BEGIN                 function_body         RETURN     END [ ; ] CLR Functions CREATE FUNCTION [ schema_name. ] function_name ( { @parameter_name [AS] [ type_schema_name. ] parameter_data_type         [ = default ] }     [ ,...n ] ) RETURNS { return_data_type | TABLE <clr_table_type_definition> }     [ WITH <clr_function_option> [ ,...n ] ]     [ AS ] EXTERNAL NAME <method_specifier> [ ; ] Method Specifier <method_specifier>::=     assembly_name.class_name.method_name Function Options <function_option>::= {     [ ENCRYPTION ]   | [ SCHEMABINDING ]   | [ RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT ]   | [ EXECUTE_AS_Clause ] } <clr_function_option>::= }     [ RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT ]   | [ EXECUTE_AS_Clause ] } Table Type Definitions <table_type_definition>:: = ( { <column_definition> <column_constraint>   | <computed_column_definition> }         [ <table_constraint> ] [ ,...n ] ) <clr_table_type_definition>::= ( { column_name data_type } [ ,...n ] ) <column_definition>::= {     { column_name data_type }     [ [ DEFAULT constant_expression ]       [ COLLATE collation_name ] | [ ROWGUIDCOL ]     ]     | [ IDENTITY [ (seed , increment ) ] ]     [ <column_constraint> [ ...n ] ] } <column_constraint>::= {     [ NULL | NOT NULL ]     { PRIMARY KEY | UNIQUE }       [ CLUSTERED | NONCLUSTERED ]         [ WITH FILLFACTOR = fillfactor         | WITH ( < index_option > [ , ...n ] )       [ ON { filegroup | "default" } ]   | [ CHECK ( logical_expression ) ] [ ,...n ] } <computed_column_definition>::= column_name AS computed_column_expression <table_constraint>::= {     { PRIMARY KEY | UNIQUE }       [ CLUSTERED | NONCLUSTERED ]             ( column_name [ ASC | DESC ] [ ,...n ] )         [ WITH FILLFACTOR = fillfactor         | WITH ( <index_option> [ , ...n ] )   | [ CHECK ( logical_expression ) ] [ ,...n ] } <index_option>::= {     PAD_INDEX = { ON | OFF }   | FILLFACTOR = fillfactor   | IGNORE_DUP_KEY = { ON | OFF }   | STATISTICS_NORECOMPUTE = { ON | OFF }   | ALLOW_ROW_LOCKS = { ON | OFF }   | ALLOW_PAGE_LOCKS ={ ON | OFF } }

备注

用户定义函数为标量值函数或表值函数。若是 RETURNS 子句指定了一种标量数据类型,则函数为标量值函数。可使用多条 Transact-SQL 语句定义标量值函数。express

若是 RETURNS 子句指定 TABLE,则函数为表值函数。根据函数主体的定义方式,表值函数可分为内联函数或多语句函数。有关详细信息,请参阅 表值用户定义函数。编程

下列语句在函数内有效:安全

  • 赋值语句。
  • TRY...CATCH 语句之外的流控制语句。
  • 定义局部数据变量和局部游标的 DECLARE 语句。
  • SELECT 语句,其中的选择列表包含为局部变量分配值的表达式。
  • 游标操做,该操做引用在函数中声明、打开、关闭和释放的局部游标。只容许使用以 INTO 子句向局部变量赋值的 FETCH 语句;不容许使用将数据返回到客户端的 FETCH 语句。
  • 修改 table 局部变量的 INSERT、UPDATE 和 DELETE 语句。
  • 调用扩展存储过程的 EXECUTE 语句。
  • 有关详细信息,请参阅建立用户定义函数(数据库引擎)。

嵌套用户定义函数

用户定义函数能够嵌套;也就是说,用户定义函数可相互调用。被调用函数开始执行时,嵌套级别将增长;被调用函数执行结束后,嵌套级别将减小。用户定义函数的嵌套级别最多可达 32 级。若是超出最大嵌套级别数,整个调用函数链将失败。架构

注意:
从 Transact-SQL 用户定义函数对托管代码的任何引用都将计入 32 级嵌套限制的一个级别。从托管代码内部调用的方法不根据此限制进行计数。 

 

 

函数属性

在 SQL Server 的早期版本中,函数只能分为肯定性函数和不肯定性函数两类。在 SQL Server 2005 中,函数具备下列属性。这些属性的值肯定了函数是否可用于持久化计算列或索引计算列。ide

属性 说明 注意

IsDeterministic函数

函数是肯定性函数仍是不肯定性函数。ui

肯定性函数中容许本地数据访问。例如,若是每次使用一组特定输入值和相同数据库状态调用函数时,函数都返回相同结果,则该函数将被标记为肯定性函数。

IsPrecise

函数是精确函数仍是不精确函数。

不精确函数包含浮点运算之类的运算。

IsSystemVerified

SQL Server 可验证函数的精度和肯定性属性。

 

SystemDataAccess

函数能够访问 SQL Server 的本地实例中的系统数据(系统目录或虚拟系统表)。

 

UserDataAccess

函数能够访问 SQL Server 的本地实例中的用户数据。

包含用户定义表和临时表,但不包含表变量。

Transact-SQL 函数的精度和肯定性属性由 SQL Server 自动肯定。有关详细信息,请参阅用户定义函数的设计指导原则。CLR 函数的数据访问权限和肯定性属性可由用户指定。有关详细信息,请参阅 Overview of CLR Integration Custom Attributes。

若要显示这些属性的当前值,请使用 OBJECTPROPERTYEX

对调用用户定义函数的计算列进行索引

若是用户定义函数具备下列属性值,则能够在索引中使用调用用户定义函数的计算列:

  • IsDeterministic = true
  • IsSystemVerified = true(计算列是持久性计算列时除外)
  • UserDataAccess = false
  • SystemDataAccess = false

有关详细信息,请参阅为计算列建立索引。

从函数中调用扩展存储过程

若是在函数中调用扩展存储过程,则该过程不能向客户端返回结果集。向客户端返回结果集的任何 ODS API 都将返回 FAIL。扩展存储过程能够链接回 SQL Server 的实例;不过,该过程不该尝试与调用扩展存储过程的函数同时联接到同一事务。

与经过批处理或存储过程进行调用类似,扩展存储过程在运行 SQL Server 的 Windows 安全账户的上下文中执行。存储过程的全部者在授予用户 EXECUTE 权限时应考虑这一点。

函数调用

可在使用标量表达式的位置调用标量值函数。这包括计算列和 CHECK 约束定义。也可使用 EXECUTE 语句执行标量值函数。在容许表表达式的状况下,可在 SELECT、INSERT、UPDATE 或 DELETE 语句的 FROM 子句中调用表值函数。有关详细信息,请参阅执行用户定义函数(数据库引擎)。

在 CLR 函数中使用参数和返回值

若是在 CLR 函数中指定了参数,则这些参数应为 SQL Server 类型,即之前为 scalar_parameter_data_type 定义的类型。有关将 SQL Server 系统数据类型与 CLR 集成数据类型或 .NET Framework 公共语言运行时数据类型进行比较的信息,请参阅 SQL Server Data Types and Their .NET Framework Equivalents。

为了使 SQL Server 在类中重载时引用正确方法,<method_specifier> 中指示的方法必须具备下列特征:

  • 接收 [ ,...n ] 中指定的参数数量。
  • 经过值而不是引用来接收全部参数。
  • 使用与 SQL Server 函数中指定的类型兼容的参数类型。

若是 CLR 函数的返回数据类型指定表类型 (RETURNS TABLE),则 <method_specifier> 中方法的返回数据类型应为 IEnumerator 或 IEnumerable 类型,且假定由函数建立者来实现接口。与 Transact-SQL 函数不一样,CLR 函数不能在 <table_type_definition> 中包含 PRIMARY KEY、UNIQUE 或 CHECK 约束。 <table_type_definition> 中指定的列的数据类型,必须与 <method_specifier> 中的方法在执行时返回的结果集中的对应列的类型匹配。建立函数时不执行上述类型检查。

有关对 CLR 函数编程的详细信息,请参阅 CLR User-Defined Functions。

不容许的 SQL 语句

下列 Service Broker 语句不能包含在 Transact-SQL 用户定义函数的定义中:

  • BEGIN DIALOG CONVERSATION
  • END CONVERSATION
  • GET CONVERSATION GROUP
  • MOVE CONVERSATION
  • RECEIVE
  • SEND

查看有关函数的信息

若要显示 Transact-SQL 用户定义函数的定义,请使用函数所在数据库中的 sys.sql_modules 目录视图。

例如:

  复制代码
USE AdventureWorks;
GO
SELECT Definition 
FROM sys.sql_modules AS m
JOIN sys.objects AS o ON m.object_id = o.object_id 
    AND TYPE IN ('FN', 'IF', 'TF');
GO
注意:
不能使用 sys.sql_modules 查看使用 ENCRYPTION 选项建立的函数定义;不过,可显示有关加密函数的其余信息。 

 

 

若要显示有关 CLR 用户定义函数的信息,请使用函数所在数据库中的 sys.assembly_modules 目录视图。

若要显示有关用户定义函数中定义的参数的信息,请使用函数所在数据库中的 sys.parameters 目录视图。

若要显示有关函数引用的对象的报表,请使用 sys.sql_dependencies

参数

schema_name 

用户定义函数所属的架构的名称。

function_name 

用户定义函数的名称。函数名称必须符合有关标识符的规则,而且在数据库中以及对其架构来讲是惟一的。

注意:
即便未指定参数,函数名称后也须要加上括号。 

 

 

@parameter_name 

用户定义函数的参数。可声明一个或多个参数。

函数最多能够有 1,024 个参数。执行函数时,若是未定义参数的默认值,则用户必须提供每一个已声明参数的值。

经过将 at 符号 (@) 用做第一个字符来指定参数名称。参数名称必须符合有关标识符的规则。参数是对应于函数的局部参数;其余函数中可以使用相同的参数名称。参数只能代替常量,而不能用于代替表名、列名或其余数据库对象的名称。

注意:
在存储过程或用户定义函数中传递参数时,或在批语句中声明和设置变量时,不会遵照 ANSI_WARNINGS。例如,若是将变量定义为 char(3) 类型,而后将其值设置为多于三个字符,则数据将截断为定义大小,而且 INSERT 或 UPDATE 语句能够成功执行。 

 

 

[ type_schema_name. ] parameter_data_type 

参数的数据类型及其所属的架构,后者为可选项。对于 Transact-SQL 函数,可使用除 timestamp 数据类型以外的全部数据类型(包括 CLR 用户定义类型)。对于 CLR 函数,可使用除 text、ntext、image 和 timestamp 数据类型以外的全部数据类型(包括 CLR 用户定义类型)。不能将非标量类型 cursor 和 table 指定为 Transact-SQL 函数或 CLR 函数中的参数数据类型。

若是未指定 type_schema_name,则 SQL Server 2005 Database Engine 将按如下顺序查找 scalar_parameter_data_type:

  • 包含 SQL Server 系统数据类型名称的架构。
  • 当前数据库中当前用户的默认架构。
  • 当前数据库中的 dbo 架构。
[ = default ] 

参数的默认值。若是定义了 default 值,则无需指定此参数的值便可执行函数。

注意:
能够为除 varchar(max) 和 varbinary(max) 数据类型以外的 CLR 函数指定默认参数值。 

 

 

若是函数的参数有默认值,则该函数检索默认值时必须指定 DEFAULT 关键字。此行为与在存储过程当中使用具备默认值的参数不一样,在后一种状况下,不提供参数一样意味着使用默认值。

return_data_type 

标量用户定义函数的返回值。对于 Transact-SQL 函数,可使用除 timestamp 数据类型以外的全部数据类型(包括 CLR 用户定义类型)。对于 CLR 函数,可使用除 text、ntext、image 和 timestamp 数据类型以外的全部数据类型(包括 CLR 用户定义类型)。不能将非标量类型 cursor 和 table 指定为 Transact-SQL 函数或 CLR 函数中的返回数据类型。

function_body 

指定一系列定义函数值的 Transact-SQL 语句,这些语句在一块儿使用不会产生负面影响(例如修改表)。function_body 仅用于标量函数和多语句表值函数。

在标量函数中,function_body 是一系列 Transact-SQL 语句,这些语句一块儿使用的计算结果为标量值。

在多语句表值函数中,function_body 是一系列 Transact-SQL 语句,这些语句将填充 TABLE 返回变量。

scalar_expression 

指定标量函数返回的标量值。

TABLE 

指定表值函数的返回值为表。只有常量和 @local_variables 能够传递到表值函数。

在内联表值函数中,TABLE 返回值是经过单个 SELECT 语句定义的。内联函数没有关联的返回变量。

在多语句表值函数中,@return_variable 是 TABLE 变量,用于存储和汇总应做为函数值返回的行。只能将 @return_variable 指定用于 Transact-SQL 函数,而不能用于 CLR 函数。

select_stmt 

定义内联表值函数的返回值的单个 SELECT 语句。

EXTERNAL NAME <method_specifier>, assembly_name.class_name.method_name 

指定将程序集与函数绑定的方法。assembly_name 必须与 SQL Server 中当前数据库内具备可见性的现有程序集匹配。class_name 必须是有效的 SQL Server 标识符,而且必须做为类存在于程序集中。若是类具备以命名空间限定的名称,该名称使用句点 (.) 来分隔命名空间的各部分,则必须使用方括号 ([ ]) 或引号 (" ") 分隔类名称。method_name 必须是有效的 SQL Server 标识符,而且必须做为静态方法存在于指定类中。

注意:
默认状况下,SQL Server 不能执行 CLR 代码。能够建立、修改和删除引用公共语言运行时模块的数据库对象;不过,只有在启用 clr enabled 选项以后,才能在 SQL Server 中执行这些引用。若要启用此选项,请使用 sp_configure。 

 

 

<table_type_definition>, ( { <column_definition> <column_constraint> ,   | <computed_column_definition> } ,   [ <table_constraint> ] [ ,...n ], ) , 

定义 Transact-SQL 函数的表数据类型。表声明包含列定义和列约束(或表约束)。表始终放在主文件组中。

< clr_table_type_definition > , ( { column_name data_type } [ ,...n ] ), 

定义 CLR 函数的表数据类型。表声明仅包含列名称和数据类型。表始终放在主文件组中。

<function_option>::= and <clr_function_option>::=

指定函数将具备如下一个或多个选项:

ENCRYPTION 

指示数据库引擎 对包含 CREATE FUNCTION 语句文本的目录视图列进行加密。使用 ENCRYPTION 能够防止将函数做为 SQL Server 复制的一部分发布。不能为 CLR 函数指定 ENCRYPTION。

SCHEMABINDING 

指定将函数绑定到其引用的数据库对象。若是其余架构绑定对象也在引用该函数,此条件将防止对其进行更改。

只有发生下列操做之一时,才会删除函数与其引用对象的绑定:

  • 删除函数。
  • 在未指定 SCHEMABINDING 选项的状况下,使用 ALTER 语句修改函数。

只有知足如下条件时,函数才能绑定到架构:

  • 函数为 Transact-SQL 函数。
  • 该函数引用的用户定义函数和视图也绑定到架构。
  • 该函数引用的对象是用由两部分组成的名称引用的。
  • 该函数及其引用的对象属于同一数据库。
  • 执行 CREATE FUNCTION 语句的用户对该函数引用的数据库对象具备 REFERENCES 权限。

不能为 CLR 函数或引用别名数据类型的函数指定 SCHEMABINDING。

RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT

指定标量值函数的 OnNULLCall 属性。若是未指定,则默认为 CALLED ON NULL INPUT。这意味着即便传递的参数为 NULL,也将执行函数体。

若是在 CLR 函数中指定了 RETURNS NULL ON NULL INPUT,它指示当 SQL Server 接收到的任何一个参数为 NULL 时,它能够返回 NULL,而无需实际调用函数体。若是 <method_specifier> 中指定的 CLR 函数的方法已具备指示 RETURNS NULL ON NULL INPUT 的自定义属性,但 CREATE FUNCTION 语句指示 CALLED ON NULL INPUT,则优先采用 CREATE FUNCTION 语句指示的属性。不能为 CLR 表值函数指定 OnNULLCall 属性。

EXECUTE AS 子句 

指定用于执行用户定义函数的安全上下文。因此,您能够控制 SQL Server 使用哪个用户账户来验证针对该函数引用的任何数据库对象的权限。

注意:
不能为内联用户定义函数指定 EXECUTE AS。 

 

 

有关详细信息,请参阅EXECUTE AS 子句 (Transact-SQL)

< column_definition >::=

定义表数据类型。表声明包含列定义和约束。对于 CLR 函数,只能指定 column_name 和 data_type。

column_name 

表中列的名称。列名称必须符合标识符规则,而且在表中必须是惟一的。column_name 能够由 1 至 128 个字符组成。

data_type 

指定列数据类型。对于 Transact-SQL 函数,可使用除 timestamp 以外的全部数据类型(包括 CLR 用户定义类型)。对于 CLR 函数,可使用除 text、ntext、image、char、varchar、varchar(max) 和 timestamp 以外的全部数据类型(包括 CLR 用户定义类型)。在 Transact-SQL 或 CLR 函数中,非标量类型 cursor 不能指定为列数据类型。

DEFAULT constant_expression 

指定当插入过程当中没有显式提供值时为列提供的值。constant_expression 能够是常量、NULL 或系统函数值。DEFAULT 定义能够应用于除具备 IDENTITY 属性的列以外的任何列。不能为 CLR 表值函数指定 DEFAULT。

COLLATE collation_name 

指定列的排序规则。若是未指定,则为此列分配数据库的默认排序规则。排序规则名称既能够是 Windows 排序规则名称,也能够是 SQL 排序规则名称。有关排序规则的列表及详细信息,请参阅 Windows 排序规则名称 (Transact-SQL)SQL 排序规则名称 (Transact-SQL)

COLLATE 子句只能用来更改数据类型为 char、varchar、nchar 和 nvarchar 的列的排序规则。

不能为 CLR 表值函数指定 COLLATE。

ROWGUIDCOL 

指示新列是行的全局惟一标识符列。对于每一个表,只能将其中的一个 uniqueidentifier 列指定为 ROWGUIDCOL 列。ROWGUIDCOL 属性只能分配给 uniqueidentifier 列。

ROWGUIDCOL 属性并不强制实现列中存储的值的惟一性。该属性也不会为插入表的新行自动生成值。若要为每列生成惟一值,请在 INSERT 语句中使用 NEWID 函数。能够指定默认值;可是,不能将 NEWID 指定为默认值。

IDENTITY 

指示新列是标识列。在为表添加新行时,SQL Server 将为该列提供惟一的增量值。标识列一般与 PRIMARY KEY 约束一块儿使用,做为表的惟一行标识符。能够将 IDENTITY 属性分配给 tinyint、smallint、int、bigint、decimal(p,0) 或 numeric(p,0) 列。每一个表只能建立一个标识列。不能将绑定默认值和 DEFAULT 约束用于标识列。必须同时指定 seed 和 increment,或者两者都不指定。若是两者都未指定,则取默认值 (1,1)。

不能为 CLR 表值函数指定 IDENTITY。

seed 

要分配给表中第一行的整数值。

increment 

要加到表中后续行的 seed 值上的整数值。

< column_constraint >::= and < table_constraint>::=

为指定列或表定义约束。对于 CLR 函数,容许的惟一约束类型为 NULL。不容许命名约束。

NULL | NOT NULL 

肯定列中是否容许空值。严格讲来,NULL 不是约束,但能够像指定 NOT NULL 那样指定它。不能为 CLR 表值函数指定 NOT NULL。

PRIMARY KEY 

一个约束,该约束经过惟一索引来强制指定列的实体完整性。在表值用户定义函数中,只能对每一个表中的一列建立 PRIMARY KEY 约束。不能为 CLR 表值函数指定 PRIMARY KEY。

UNIQUE 

一个约束,该约束经过惟一索引为一个或多个指定列提供实体完整性。一个表能够有多个 UNIQUE 约束。不能为 CLR 表值函数指定 UNIQUE。

CLUSTERED | NONCLUSTERED 

指示为 PRIMARY KEY 或 UNIQUE 约束建立汇集索引仍是非汇集索引。PRIMARY KEY 约束使用 CLUSTERED,而 UNIQUE 约束使用 NONCLUSTERED。

只能为一个约束指定 CLUSTERED。若是为 UNIQUE 约束指定了 CLUSTERED,而且指定了 PRIMARY KEY 约束,则 PRIMARY KEY 使用 NONCLUSTERED。

不能为 CLR 表值函数指定 CLUSTERED 和 NONCLUSTERED。

CHECK 

一个约束,该约束经过限制可输入一列或多列中的可能值来强制实现域完整性。不能为 CLR 表值函数指定 CHECK 约束。

logical_expression 

返回 TRUE 或 FALSE 的逻辑表达式。

<computed_column_definition>::=

指定计算列。有关计算列的详细信息,请参阅 CREATE TABLE (Transact-SQL)

column_name 

计算列的名称。

computed_column_expression 

定义计算列的值的表达式。

<index_option>::=

为 PRIMARY KEY 或 UNIQUE 索引指定索引选项。有关索引选项的详细信息,请参阅 CREATE INDEX (Transact-SQL)

PAD_INDEX = { ON | OFF

指定索引填充。默认值为 OFF。

FILLFACTOR = fillfactor 

指定一个百分比,指示在建立或更改索引期间,数据库引擎 对各索引页的叶级填充的程度。fillfactor 必须为介于 1 至 100 之间的整数值。默认值为 0。

IGNORE_DUP_KEY = { ON | OFF

指定当对惟一汇集索引或惟一非汇集索引的多行插入事务中出现重复键值时的错误响应。默认值为 OFF。

STATISTICS_NORECOMPUTE = { ON | OFF

指定是否从新计算分布统计信息。默认值为 OFF。

ALLOW_ROW_LOCKS = { ON | OFF } 

指定是否容许行锁。默认值为 ON。

ALLOW_PAGE_LOCKS = { ON | OFF } 

指定是否容许页锁。默认值为 ON。

权限

须要在数据库中具备 CREATE FUNCTION 权限,并对建立函数时所在的架构具备 ALTER 权限。若是函数指定用户定义类型,则须要对该类型具备 EXECUTE 权限。

示例

A. 使用计算 ISO 周的标量值用户定义函数

如下示例将建立用户定义函数 ISOweek。此函数使用日期参数来计算 ISO 周数。要使此函数能正确计算,必须在调用该函数前调用 SET DATEFIRST 1

另外,该示例将显示如何使用 EXECUTE AS 子句指定可在其中执行存储过程的安全上下文。在该示例中,CALLER 选项指定该过程将在调用该过程的用户的上下文中执行。您还能够指定 SELF、OWNER 和 user_name 等其余选项。有关详细信息,请参阅EXECUTE AS 子句 (Transact-SQL)

  复制代码
USE AdventureWorks;
GO
IF OBJECT_ID (N'dbo.ISOweek', N'FN') IS NOT NULL
    DROP FUNCTION dbo.ISOweek;
GO
CREATE FUNCTION dbo.ISOweek (@DATE datetime)
RETURNS int
WITH EXECUTE AS CALLER
AS
BEGIN
     DECLARE @ISOweek int
     SET @ISOweek= DATEPART(wk,@DATE)+1
          -DATEPART(wk,CAST(DATEPART(yy,@DATE) as CHAR(4))+'0104')
--Special cases: Jan 1-3 may belong to the previous year
     IF (@ISOweek=0) 
          SET @ISOweek=dbo.ISOweek(CAST(DATEPART(yy,@DATE)-1 
               AS CHAR(4))+'12'+ CAST(24+DATEPART(DAY,@DATE) AS CHAR(2)))+1
--Special case: Dec 29-31 may belong to the next year
     IF ((DATEPART(mm,@DATE)=12) AND 
          ((DATEPART(dd,@DATE)-DATEPART(dw,@DATE))>= 28))
          SET @ISOweek=1
     RETURN(@ISOweek)
END;
GO

下面是函数调用。请注意,DATEFIRST 设置为 1

  复制代码
SET DATEFIRST 1;
SELECT dbo.ISOweek(CONVERT(DATETIME,'12/26/2004',101)) AS 'ISO Week';

下面是结果集: 

  复制代码
ISO Week
----------------
52

B. 建立内联表值函数

如下示例将返回内联表值函数。对于销售给商店的每一个产品,该函数返回三列,分别为 ProductIDName 以及各个商店年初至今总数的累计 YTD Total

  复制代码
USE AdventureWorks;
GO
IF OBJECT_ID (N'Sales.fn_SalesByStore', N'IF') IS NOT NULL
    DROP FUNCTION Sales.fn_SalesByStore;
GO
CREATE FUNCTION Sales.fn_SalesByStore (@storeid int)
RETURNS TABLE
AS
RETURN 
(
    SELECT P.ProductID, P.Name, SUM(SD.LineTotal) AS 'YTD Total'
    FROM Production.Product AS P 
      JOIN Sales.SalesOrderDetail AS SD ON SD.ProductID = P.ProductID
      JOIN Sales.SalesOrderHeader AS SH ON SH.SalesOrderID = SD.SalesOrderID
    WHERE SH.CustomerID = @storeid
    GROUP BY P.ProductID, P.Name
);
GO

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

  复制代码
SELECT * FROM Sales.fn_SalesByStore (602);

C. 建立多语句表值函数

如下示例建立了表值函数 fn_FindReports(InEmpID)。若是提供一个有效雇员 ID,该函数将返回一个表,该表对应于直接或间接向该雇员报告的全部雇员。该函数使用递归公用表表达式 (CTE) 来生成雇员的层次结构列表。有关递归 CTE 的详细信息,请参阅 WITH common_table_expression (Transact-SQL)

  复制代码
USE AdventureWorks;
GO
IF OBJECT_ID (N'dbo.fn_FindReports', N'TF') IS NOT NULL
    DROP FUNCTION dbo.fn_FindReports;
GO
CREATE FUNCTION dbo.fn_FindReports (@InEmpID INTEGER)
RETURNS @retFindReports TABLE 
(
    EmployeeID int primary key NOT NULL,
    Name nvarchar(255) NOT NULL,
    Title nvarchar(50) NOT NULL,
    EmployeeLevel int NOT NULL,
    Sort nvarchar (255) NOT NULL
)
--Returns a result set that lists all the employees who report to the 
--specific employee directly or indirectly.*/
AS
BEGIN
   WITH DirectReports(Name, Title, EmployeeID, EmployeeLevel, Sort) AS
    (SELECT CONVERT(Varchar(255), c.FirstName + ' ' + c.LastName),
        e.Title,
        e.EmployeeID,
        1,
        CONVERT(Varchar(255), c.FirstName + ' ' + c.LastName)
     FROM HumanResources.Employee AS e
          JOIN Person.Contact AS c ON e.ContactID = c.ContactID 
     WHERE e.EmployeeID = @InEmpID
   UNION ALL
     SELECT CONVERT(Varchar(255), REPLICATE ('| ' , EmployeeLevel) +
        c.FirstName + ' ' + c.LastName),
        e.Title,
        e.EmployeeID,
        EmployeeLevel + 1,
        CONVERT (Varchar(255), RTRIM(Sort) + '| ' + FirstName + ' ' + 
                 LastName)
     FROM HumanResources.Employee as e
          JOIN Person.Contact AS c ON e.ContactID = c.ContactID
          JOIN DirectReports AS d ON e.ManagerID = d.EmployeeID
    )
-- copy the required columns to the result of the function 
   INSERT @retFindReports
   SELECT EmployeeID, Name, Title, EmployeeLevel, Sort
   FROM DirectReports 
   RETURN
END;
GO
-- Example invocation
SELECT EmployeeID, Name, Title, EmployeeLevel
FROM dbo.fn_FindReports(109)
ORDER BY Sort;

D. 建立 CLR 函数

如下示例假定在本地计算机的默认位置安装了 SQL Server Database Engine samples,而且已编译了 StringManipulate.csproj 示例应用程序。有关详细信息,请参阅 可以识别补充字符的字符串操做。

该示例将建立 CLR 函数 len_s。在建立该函数以前,程序集 SurrogateStringFunction.dll 已在本地数据库中注册。

  复制代码
DECLARE @SamplesPath nvarchar(1024);
-- You may have to modify the value of the this variable if you have
--installed the sample someplace other than the default location.
SELECT @SamplesPath = REPLACE(physical_name, 'Microsoft SQL Server/MSSQL.1/MSSQL/DATA/master.mdf', 'Microsoft SQL Server/90/Samples/Engine/Programmability/CLR/') 
    FROM master.sys.database_files 
    WHERE name = 'master';

CREATE ASSEMBLY [SurrogateStringFunction]
FROM @SamplesPath + 'StringManipulate/CS/StringManipulate/bin/debug/SurrogateStringFunction.dll'
WITH PERMISSION_SET = EXTERNAL_ACCESS;
GO

CREATE FUNCTION [dbo].[len_s] (@str nvarchar(4000))
RETURNS bigint
AS EXTERNAL NAME [SurrogateStringFunction].[Microsoft.Samples.SqlServer.SurrogateStringFunction].[LenS];
GO
相关文章
相关标签/搜索