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

 

posted @ 2013-04-28 17:39  学海无涯1999  阅读(740)  评论(0)    收藏  举报