注册 | 登录 忘记密码? 51cto首页 | 博客 | 论坛 | 招聘
热点文章 SWAT—Samba WEB管理..
 帮助

创建用户自定义标量函数


2007-04-18 22:41:23
 标签:函数 SQL CASE   [推送到技术圈]

版权声明:原创作品,谢绝转载!否则将追究法律责任。
 
目的:你们公司所销售的产品遵从基于产品类别的变化税率。一些产品,比如饮料是高税率产品,而像佐料这样的产品是免税。你决定建立一个用户自定义函数来封装这个收税的逻辑。这个用户自定义函数为管理税率与简化必须重复的逻辑部分提供了一个中心场所。
    创建一个名称为fn_TaxRate的标量用户自定义函数,该函数封装了CASE语句,它接受一个参数@ProdID int并返回一个numeric(5,4)数据类型的值。
 
l  测试函数
 
在本过程中,用从产品表中选择列的方法来测试你刚才创建的函数。
执行下面的SELECT语句,从产品表中选择ProductName,UnitPrice,CategoryID,TaxRate以及一个计算值PriceWithTax。
 
select productname,unitprice,categoryid,dbo.fn_taxrate(productid) as taxrate,
unitprice*dbo.fn_taxrate(productid) as pricewithtax from products
 
TaxRate 列对每个产品都应该包含这样的值:1.00或者1.05或者1.10。
PriceWithTax列应该包含TaxRate列与UnitPrice列的乘积。
代码:
USE Northwind
GO
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, Northwind.dbo.fn_TaxRate(ProductID) AS TaxRate,
UnitPrice * Northwind.dbo.fn_TaxRate(ProductID) AS PriceWithTax FROM Products

本文出自 “┿⊙清风月影┿” 博客,谢绝转载!





    文章评论
 
2007-04-19 11:16:44
有1没有2???
支持下

2007-04-19 22:00:35
先抢个沙发再说。。。期待下集。

2007-04-20 18:31:18
2:创建一个多语句表值用户自定义函数
本练习中,将创建一个多语句表值用户自定义函数,来查询Northwind数据库中的Employees表,并显示所有直接和非直接的汇报者。
在Northwind数据库中的Employees表中,含有一个名称为ReportsTO的列,该列包含了每个员工要向其汇报的管理者的雇员ID号。
在本练习中,将创建一个带有一个管理者EmployeeID号为参数的用户自定义函数,并通过Employee表进行迭带,收集向任何层次上指定管理者汇报的雇员的信

息。

测试函数

在这个过程中,将通过从fn_Findreports函数中选择列的方式来测试你所创建的函数。
1、执行下面的SELECT语句,从fn_Findreports函数中选择EmployeeID、Name、Title和MgrEmployeeID列.

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

这条SELECT语句返回向Steven Buchanan(EmployeeID 5)汇报的雇员的名称的。

2、执行下面的SELECT语句,从fn_findreports函数中选择employeeid、name、title和mgremployeeid列
select employeeid,[name],title,mgremployeeid from dbo.fnfindreportss(2)
这条SELECT语句返回一个包含向Abdrew Fykker(EmployeeID 2)汇报的雇员的名称的表。

--代码如下:
use Northwind
go

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)
as
begin
     declare @RowsAdded int
     insert @reports
           select EmployeeID, Name = FirstName + ' ' + LastName, Title, ReportsTo, 0
           from EMPLOYEES
           where ReportsTo = @InEmployeeID

     set @RowsAdded = @@rowcount

     whlie @RowsAdded > 0
     begin
           update @reports
           set processed = 1
           where processed = 0
           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

           update @reports
           set processed = 2
           where processed = 1
     end

return
end
go

select EmployeeID,[Name],Title,MgrEmployeeID from dbo.fn_Findreports(5)

select employeeid,[name],title,mgremployeeid from dbo.fn_Findreports(2)

2007-04-20 18:45:36
这是我前几天做的几道练习题哈,各位多多指教!

2007-04-20 20:55:13
真好哦 下次在来看看啊

2007-04-21 15:09:13
--断言:多个表上的完整性约束
--假如我们希望强制实现约束“船只的数目加上水手的数目要少于100”(这个条件可能用于鉴定一个“小”的水手俱乐部),则会有下面的表约束:
create table sailors
(
  sid int primary key not null,
  sname char(10) not null,
rating int not null,
age real not null,
check(rating>=1 and rating <=10)
check(select count(s.sid) from sailors s)+(select count(b.bid)from boats b)<100
)
--很明显,这个解决方案有两个缺点,尽管它以完全对称的方式与boats关联,但它还是与sailors相关联,更重要的,如果sailors表是空的,那么这个约束就被定义成总是保持的,尽管boats可能多于100行!可扩展这个约束的规范来检查其是否为空,但最好还是创建一个断言,如下所示:
create assertion smallclub
check((select count(s.sid)from sailors s)+(select count(b.bid)from boats b)<100)

2007-04-25 15:21:48
呵呵,这篇不错。
挺清楚的。

 

发表评论

昵   称:
验证码:  点击图片可刷新验证码  博客过2级,无需填写验证码
内   容: