SQL Server 函数种类详解
文章来自:博客园-鸡尾虾的壳
1.标量函数
标量函数:返回单个数据值,返回类型可以是除 text、ntext、image、cursor 和 timestamp 外的任何数据类型。
标量函数:分为内联标量函数和多语句标量函数。
内联标量函数:没有函数体,标量值是单个语句的结果。
多语句标量函数:定义在 BEGIN...END 块中的函数体包含一系列返回单个值的 Transact-SQL 语句。
多语句标量函数范例:
CREATE FUNCTION dbo.ufnGetInventoryStock(@ProductID int) RETURNS int AS BEGIN DECLARE @ret int; SELECT @ret = SUM(p.Quantity) FROM Production.ProductInventory p WHERE p.ProductID = @ProductID AND p.LocationID = '6'; IF (@ret IS NULL) SET @ret = 0; RETURN @ret; END;
2.标值函数
表值函数:返回 table 数据类型,分为内联表值函数和多语句表值函数。
内联表值函数:没有函数主体。
区别:如果 RETURNS 子句指定的 TABLE 不附带列的列表,则该函数为内嵌表值函数。
如果 RETURNS 子句指定的 TABLE 类型带有列及其数据类型,则该函数是多语句表值函数。
内联表值函数范例:
CREATE FUNCTION Sales.ufn_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 );
多语句表值函数:在 BEGIN...END 语句块中定义的函数体包含一系列 Transact-SQL 语句,这些语句可生成行并将其插入将返回的表中。
多语句表值函数范例:
CREATE FUNCTION dbo.ufn_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.ufn_FindReports(109) ORDER BY Sort;
多语句表值函数中只允许使用下面的语句类型:
赋值语句。
控制流语句。
DECLARE 语句,该语句定义函数局部的数据变量和游标。
SELECT 语句,该语句包含带有表达式的选择列表,其中的表达式将值赋予函数的局部变量。
游标操作,该操作引用在函数中声明、打开、关闭和释放的局部游标。只允许使用以 INTO 子句向局部变量赋值的 FETCH 语句;不允许使用将数据返回到客户端的 FETCH 语句。
INSERT、UPDATE 和 DELETE 语句,这些语句修改函数的局部 table 变量。
EXECUTE 语句调用扩展存储过程。
3.内置函数
SQL Server 提供了内置函数帮助您执行各种操作。这些函数不能修改。可以在 Transact-SQL 语句中使用内置函数,完成以下操作:
从 SQL Server 系统表中访问信息而不直接访问系统表。有关详细信息,请参阅使用系统函数。
执行常见任务,例如 SUM、GETDATE 或 IDENTITY。有关详细信息,请参阅Functions (Transact-SQL)。
内置函数返回标量数据类型或 table 数据类型。例如,如果成功执行了最后一条 Transact-SQL 语句,@@ERROR 将返回 0。如果该语句生成错误,则 @@ERROR 将返回错误号。而函数 SUM(parameter) 将返回参数的所有值的和。
4.函数与存储过程的区别
函数不能用于执行一系列改变物理数据库状态的操作。BEGIN...END 块中的语句不能有任何副作用。函数副作用是指对具有函数外作用域(例如数据库表的修改)的资源状态的任何永久性更改。函数中的语句唯一能做的更改是对函数上的局部对象(如局部游标或局部变量)的更改。不能在函数中执行的操作包括:对数据库表的修改,对不在函数上的局部游标进行操作,发送电子邮件,尝试修改目录,以及生成返回至用户的结果集。
5.用户定义函数中不允许使用会对每个调用返回不同数据的内置函数,用户定义函数中不允许使用以下内置函数:
@@CONNECTIONS @@PACK_SENT GETDATE @@CPU_BUSY @@PACKET_ERRORS GetUTCDate @@IDLE @@TIMETICKS NEWID @@IO_BUSY @@TOTAL_ERRORS RAND @@MAX_CONNECTIONS @@TOTAL_READ TEXTPTR @@PACK_RECEIVED @@TOTAL_WRITE

浙公网安备 33010602011771号