示例 a. 计算 iso 周的标量值用户定义函数 下例中,用户定义函数 isoweek 取日期参数并计算 iso 周数。为了正确计算该函数,必须在调用该函数前唤醒调用 set datefirst 1。
create function isoweek (@date datetime) returns int as begin declare @isoweek int set @isoweek= datepart(wk,@date)+1 -datepart(wk,cast(datepart(yy,@date) as char(4))+'0104') --special cases: jan 1-3 may belong to the previous year if (@isoweek=0) set @isoweek=dbo.isoweek(cast(datepart(yy,@date)-1 as char(4))+'12'+ cast(24+datepart(day,@date) as char(2)))+1 --special case: dec 29-31 may belong to the next year if ((datepart(mm,@date)=12) and ((datepart(dd,@date)-datepart(dw,@date))>= 28)) set @isoweek=1 return(@isoweek) end
下面是函数调用。注意 datefirst 设置为 1。
set datefirst 1 select master.dbo.isoweek('12/26/1999') as 'iso week' 下面是结果集。
iso week ---------------- 52
b. 内嵌表值函数 下例返回内嵌表值函数。
use pubs go create function salesbystore (@storeid varchar(30)) returns table as return (select title, qty from sales s, titles t where s.stor_id = @storeid and t.title_id = s.title_id)
create function fn_findreports (@inempid nchar(5)) returns @retfindreports table (empid nchar(5) primary key, empname nvarchar(50) not null, mgrid nchar(5), title nvarchar(30)) /*returns a result set that lists all the employees who report to given employee directly or indirectly.*/ as begin declare @rowsadded int -- table variable to hold accumulated results declare @reports table (empid nchar(5) primary key, empname nvarchar(50) not null, mgrid nchar(5), title nvarchar(30), processed tinyint default 0) -- initialize @reports with direct reports of the given employee insert @reports select empid, empname, mgrid, title, 0 from employees where empid = @inempid 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 with processed=1.*/ update @reports set processed = 1 where processed = 0 -- insert employees who report to employees marked 1. insert @reports select e.empid, e.empname, e.mgrid, e.title, 0 from employees e, @reports r where e.mgrid=r.empid and e.mgrid <> e.empid and r.processed = 1 set @rowsadded = @@rowcount /*mark all employee records whose direct reports have been found in this iteration.*/ update @reports set processed = 2 where processed = 1 end
-- copy to the result of the function the required columns insert @retfindreports select empid, empname, mgrid, title from @reports return end go
-- example invocation select * from fn_findreports('11234') go