實現用戶自定義函數(轉)

實現用戶自定義函數
我們在這一章裏討論了實現用戶自定義函數的方法,解釋三種類型的用戶自定義,併爲它們分別提供了一個實例!
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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章