sql server 用户自定义表
UDF和存储过程的主要区别在于返回结果的方式,为了能支持多种不同的返回值,UDF
比存储过程有更多的限制
UDF有两种类型:返回标量值的UDF,返回表的UDF
创建UDF的基本语法:
Create function [<schema name>.]<function name>
([<@parameter name>[as][<schema name>.]<data type>[=<default value>[readonly]]
[,…n]])
Returns [<scalar type>|table[(<table definition>)]]
[with[encryption]|[schemabinding]|
[returns null on null input|called on null input]|[execute as [
Caller|self|owner|<’user name’>]]
]
[as][external name<external method>|
Begin
[<function statements>
[return <type as defined in returns clause>|return (<select statement>)]
end]][;]
可以返回除了blob,游标,和时间戳以外的的任何有效的数据类型,而且返回的是有意义的数据。可以在查询中
内联执行函数,而使用存储过程则不行
Create function dbo.dayonly(@date datetime)
Returns varchar(12)
As
Begin
Return convert(varchar(12),@date,101);
End
Create function dbo.aeragePrice()
Returns money
With schemabinding
As
Begin
Return(select avg(listprice)from production.product);
End
Go
在一个udf中嵌套另一个udf 是完全合法的
返回表的udf:
Create function dbo.fncontactlist()
Returns table
As
Return (select businessentityid,lastname+’,’+firstname as name from person.person);
========================================================================
Create function dbo.fngetreports(@employeeid as int)
Returns @reports table
(
Employeeid int not null,
Managerid int null
)
As
Begin
Declare @employee as int;
Insert into @reports
Select employeeid,managerid
From humanresources.employee2
Where employeeid=@employeeid;
Select @employee=min(employeeid)
From humanresources.employee2
Where managerid=@employeeid;
While @employee is not null
Begin
Insert into @reports
Select *
From fngetreports(@employee);
Select @employee=min(employeeid)
From humanresources.employee2
Where employeeid>@employee
And managerid=@employeeid;
End
Return;
End
UDF可以是确定性的也可以是非确定性的。如果给定一组特定的有效输入,每次函数就都能返回相同的结果,那么
就说该函数时确定性的
为了达到确定性的要求,函数必须满足以下4个条件:
函数必须是模式绑定的
函数引用的所有其他函数,都必须是确定性的
不能引用在函数外部定义的表
不能使用扩展存储过程
可以使用 select objectproperty(object_id(‘dayonly’),’isdeterministic’);查询函数是否是确定性的函数