实现用户自定义函数(转)

实现用户自定义函数
我们在这一章里讨论了实现用户自定义函数的方法,解释三种类型的用户自定义,并为它们分别提供了一个实例!
1
.何为用户自定义函数:我们可以通过SQL SERVER2000设计自己的函数,来补充和扩展系统提供的内置函数!用户自定义函数的输入参数可以有多个,也可以没有,但是其数据类型不能为时间戳,游标和表,同时用户自定义函数的返回值或者是个标题,或者是个表!

有三种类型的用户自定义函数:

1
 标量函数:与内置函数相似。

2
 多语句表值函数:返回由一个或是多个TSQL语句建造的表,这一动作与存储过程类似,但是与存储过程不同的是它能够像视图一样,在SELECT语句中的FROM语句中引用!它可用来代替返回表的存储过程,这可大大提高SQL SERVER的性能!

3
 嵌入式表值函数:它返回一个表,该表是单条SELECT语句的结果,这和视图相似,但在参数的使用上比视图有更大的灵活性,在视图上我们不能够使用参数,但是在嵌入式表值函数中可以使用参数!我们可以使用嵌入式表值函数来创建参数化视图!

2
.定义用户自定义函数:下面我们就进行用户自定义函数的创建的,修改和删除!

1
.创建用户自定义函数:我们使用create 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 ]
BEGIN
    function_body
    RETURN scalar_expression
END
下面我们来看个例子:

create function fn_nNewRegion
(@myinput nvarchar(30))
returns nvarchar(30)
begin
if @myinput is null
set @myinput=’not applicable’
return @myinput
end
我们不能够在用户自定义函数的函数体内包括不确定性函数。不确定性函数也是一种函数,它是在相同的输入条件下,每次返回不同的值。如:GETDATE()等。但是我们可以在输入参数中使用它!


我们可以使用模式绑定创建函数:此时我们将把函数绑定到它所引用的数据库对象上。如果一个函数通过使用模式绑定选项被创建,则这个函数所引用的数据库对象不能(通过使用ALTER语句或DROP语句)被修改或删除!但是在它创建的时候它所引用的视图或用户自定义函数也都是一种模式绑定,还要求函数和对象在一个数据库内!

   当我们修改函数的时候,SQL SERVER将用新的函数定义来代替已有的函数定义。但是像视图和存储过程一样,仍保留所赋予的权限!
――alter function…
      
删除函数:
drop function….
3.
用户自定义函数举例:   

函数类型 Returns子句指定的数据类型 是否使用BEGIN。。。

END SELECT 
语句的个数 使用

标量函数 数据类型 使用 多个 在上结果集上使用复杂

多语句表值函数函数 表(表结构) 使用 多个 代替返回表的存储过程

嵌入式表值函数  不使用(return 单个 创建带参数的视图

实验1。创建用户自定义标量函数:计算税率(因为有些产品是免税的,而有些是高税的)

   
CREATE FUNCTION fn_TaxRate 
   (@ProdID INT)
RETURNS numeric(5,4)
AS
BEGIN
RETURN
(SELECT 
   CASE CategoryID 
      WHEN 1 THEN 1.10
      WHEN 2 THEN 1
      WHEN 3 THEN 1.10
      WHEN 4 THEN 1.05
      WHEN 5 THEN 1
      WHEN 6 THEN 1.05
      WHEN 7 THEN 1
      WHEN 8 THEN 1.05
   END
FROM Products  
WHERE ProductID = @ProdID)
END
GO
测试:

SELECT ProductName, UnitPrice, CategoryID,dbo.fn_TaxRate(ProductID) AS TaxRate, 
UnitPrice * Northwind.dbo.fn_TaxRate(ProductID) AS PriceWithTax FROM Products
实验2。创建一个多语句表值函数:创建一个带有管理者EmployeeID号为参数的函数,并通过employee表进行迭带,悼念向任何层次上指定管理者汇报的雇员的信息。


Create FUNCTION fn_FindReports (@InEmployeeID char(5))
RETURNS @reports TABLE
  (EmployeeID char(5) PRIMARY KEY,
  Name nvarchar(40) NOT NULL,
  Title nvarchar(30),
  MgrEmployeeID int,
  processed tinyint default 0)

-- Returns a result set that lists all the employees who 
-- report to a given employee directly or indirectly

AS
BEGIN
 DECLARE @RowsAdded int

 -- Initialize @reports with direct reports of the given employee
 INSERT @reports
  SELECT EmployeeID, Name = FirstName + ' ' + LastName, Title, ReportsTo, 0
  FROM Employees
  WHERE ReportsTo = @InEmployeeID

 SET @RowsAdded = @@rowcount

 -- While new employees were added in the previous iteration
 WHILE @RowsAdded > 0
 BEGIN
  -- Mark all employee records whose direct reports are going to be
  -- found in this iteration
  UPDATE @reports
  SET processed = 1
  WHERE processed = 0
  
  -- Insert employees who report to employees marked 1
  INSERT @reports
   SELECT e.EmployeeID, Name = FirstName + ' ' + LastName , e.Title, e.ReportsTo, 0
   FROM Employees e, @reports r
   WHERE  e.ReportsTo = r.EmployeeID
   AND r.processed = 1

  SET @RowsAdded = @@rowcount

  -- Mark all employee records whose direct reports hae been
  -- found in this iteration
  UPDATE @reports
  SET processed = 2
  WHERE processed = 1
 END

RETURN -- Provides the value of @reports as the result
END
GO
测试:


SELECT EmployeeID, [Name], Title, MgrEmployeeID FROM dbo.fn_FindReports(5)

SELECT EmployeeID, [Name], Title, MgrEmployeeID FROM dbo.fn_FindReports(2)

实验3。创建嵌入式表值函数:创建一个嵌入式表值函数来替代视图,这个函数返回超过一定美元数量的货物订单

CREATE FUNCTION fn_LargeFreight 
   (@FreightAmt money)
RETURNS TABLE 
AS 
RETURN
(  SELECT S.ShipperID, S.CompanyName,
      O.OrderID, O.ShippedDate, O.Freight
   FROM Shippers AS S JOIN Orders AS O
      ON S.ShipperID = O.ShipVia
   WHERE O.Freight > @FreightAmt
)
测试:

SELECT * FROM fn_LargeFreight(600)
  
发布了7 篇原创文章 · 获赞 10 · 访问量 6万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章