执行用户定义函数(数据库引擎)
可以在查询、其他语句或表达式(例如计算列或字符串表达式)中调用用户定义函数。可使用 EXECUTE 语句执行标量值函数。
调用返回标量值的用户定义函数
可以在 Transact-SQL 语句中允许使用标量表达式的任何位置调用返回标量值(与标量表达式的数据类型相同)的用户定义函数。必须使用至少由两部分组成名称的函数来调用标量值函数。有关多部分名称的详细信息,请参阅Transact-SQL 语法约定 (Transact-SQL)。
查询
以下场合可以使用返回标量值的用户定义函数:
作为 SELECT 语句的 select_list 中的 expression:
USE AdventureWorks; GO SELECT ProductID, ListPrice, dbo.ufnGetProductDealerPrice(ProductID, StartDate) AS DealerPrice, StartDate, EndDate FROM Production.ProductListPriceHistory WHERE ListPrice > .0000 ORDER BY ProductID, StartDate; GO
作为 WHERE 或 HAVING 子句谓词中的 expression 或 string_expression:
USE AdventureWorks; GO SELECT ProductID, ListPrice, StartDate, EndDate FROM Production.ProductListPriceHistory WHERE dbo.ufnGetProductDealerPrice(ProductID, StartDate) > .0000 ORDER BY ProductID, StartDate; GO
作为 GROUP BY 子句中的 group_by_expression。
作为 ORDER BY 子句中的 order_by_expression。
作为 UPDATE 语句 SET 子句中的 expression:
USE AdventureWorks; GO UPDATE Production.ProductListPriceHistory SET ListPrice = dbo.ufnGetProductDealerPrice(ProductID, StartDate) WHERE ProductID > 900; GO
作为 INSERT 语句 VALUES 子句中的 expression:
这些场合引用的用户定义函数逻辑上每行执行一次。
CHECK 约束
如果传递给函数的参数值仅引用表中的列或常量,则可以在 CHECK 约束中调用返回标量值的用户定义函数。查询处理器每次检查约束时,都使用与所检查的当前行相关联的参数值调用函数。表的所有者还必须是由表的 CHECK 约束调用的用户定义函数的所有者。
DEFAULT 定义
如果传递给函数的参数值仅包含常量,则用户定义函数可作为 DEFAULT 定义的 constant_expression 来调用。表的所有者还必须是由表的 DEFAULT 定义调用的用户定义函数的所有者。
计算列
如果传递给函数的参数值仅引用表中的列或常量,则可由计算列调用函数。表的所有者还必须是由表的计算列调用的用户定义函数的所有者。
赋值运算符
赋值运算符 (left_operand = right_operand) 可调用用户定义函数,以便在指定为右操作数的表达式中返回标量值。
控制流语句
控制流语句可在其布尔表达式中调用返回标量值的用户定义函数。
CASE 表达式
任何 CASE 表达式中都可调用返回标量值的用户定义函数。
PRINT 语句
返回字符串的用户定义函数可作为 PRINT 语句的 string_expr 表达式调用。
函数和存储过程
返回标量值的用户定义函数也可以引用函数参数。
存储过程中的 RETURN integer_expression 语句可以将返回整数的用户定义函数作为 integer_expression 调用。
用户定义函数中的 RETURN return_type_spec 语句可调用返回标量数据类型(如 return_type_spec)的用户定义函数,只要被调用的用户定义函数返回的值可隐式转换为调用函数的返回数据类型。
执行返回标量值的用户定义函数
可采用与存储过程相同的方式执行返回标量值的用户定义函数。当执行返回标量值的用户定义函数时,指定参数的方式与为存储过程指定参数的方式相同:
参数值不括在括号中。
可以指定参数名称。
如果指定参数名称,则参数值的序列不必与参数的序列相同。
下面的示例创建了一个返回小数标量值的用户定义函数。
IF OBJECT_ID(N'dbo.ufn_CubicVolume', N'FN') IS NOT NULL
DROP FUNCTION dbo.ufn_CubicVolume;
GO
CREATE FUNCTION dbo.ufn_CubicVolume
-- Input dimensions in centimeters.
(@CubeLength decimal(4,1), @CubeWidth decimal(4,1),
@CubeHeight decimal(4,1) )
RETURNS decimal(12,3) -- Cubic Centimeters.
WITH SCHEMABINDING
AS
BEGIN
RETURN ( @CubeLength * @CubeWidth * @CubeHeight )
END;
GO
下面的示例执行 dbo.ufn_CubicVolume 函数。使用 Transact-SQL EXECUTE 语句时,参数的标识顺序与函数定义中的参数的标识顺序不同:
DECLARE @MyDecimalVar decimal(12,3);
EXEC @MyDecimalVar = dbo.ufn_CubicVolume @CubeLength = 12.3,
@CubeHeight = 4.5, @CubeWidth = 4.5;
SELECT @MyDecimalVar;
GO
下面的示例在不指定参数名称的情况下执行 dbo.ufn_CubicVolume 函数:
DECLARE @MyDecimalVar decimal(12,3);
EXEC @MyDecimalVar = dbo.ufn_CubicVolume 12.3, 4.5, 4.5;
SELECT @MyDecimalVar;
GO
还可以使用 ODBC CALL 语法从 OLE DB 或 ODBC 应用程序中执行 dbo.ufn_CubicVolume 函数:
-- First use SQLBindParam to bind the return value parameter marker
-- to a program variable of the appropriate type
SQLExecDirect(hstmt,
"{ CALL ? = dbo.ufn_CubicVolume(12.3, 4.5, 4.5) }",
SQL_NTS);
调用返回表数据类型的用户定义函数
可以在 SELECT、INSERT、UPDATE 或 DELETE 语句的 FROM 子句中允许使用表表达式的位置调用返回 table 的用户定义函数。可以在调用返回表的用户定义函数后加上可选的表别名。下面的示例说明了在 SELECT 语句的 FROM 子句中调用表值函数 dbo.ufnGetContactInformation。
USE AdventureWorks;
GO
SELECT ContactID, FirstName, LastName, JobTitle, ContactType
FROM dbo.ufnGetContactInformation(2200);
GO
SELECT ContactID, FirstName, LastName, JobTitle, ContactType
FROM dbo.ufnGetContactInformation(5);
GO
当在子查询的 FROM 子句中调用返回表的用户定义函数时,函数参数不能引用外部查询中的任何列。
如果 SELECT 语句的 FROM 子句引用了返回表的用户定义函数,则静态的只读游标是可在该 SELECT 语句中打开的唯一游标类型。
引用返回 table 的用户定义函数的 SELECT 语句调用该函数一次。
调用内置表值函数
以下是一些返回表值的内置表值函数。对这些内置用户定义函数的调用可以无限定,也可以使用 sys 架构限定符。对于内置表值函数应该使用 sys 架构限定符,因为该限定符可以防止与具有相同名称的用户定义函数发生冲突。以下示例说明了如何调用系统内置函数 fn_helpcollations。
SELECT *
FROM sys.fn_helpcollations();
GO
对表值函数应用提示
创建用户定义函数时,可以在构成函数定义的任何查询中应用表提示。应用于引用 Transact-SQL 表值函数的视图的提示也应用于这些函数。这些函数可能与函数定义中的提示相冲突。有关详细信息,请参阅视图解析。
不能应用引用 CLR 表值函数的视图上的提示。
注意 |
---|
未来版本的 SQL Server 中会删除数据库引擎将视图上的提示应用于属于视图定义的多语句表值函数的功能。 |
不能将表提示应用于查询的 FROM 子句中的任何表值函数的结果。