【问题标题】:How do I write a User Defined Function?如何编写用户定义函数?
【发布时间】:2009-01-15 03:27:10
【问题描述】:
我想把它写成用户定义的函数:
private double Score(Story s){
DateTime now = DateTime.Now;
TimeSpan elapsed = now.Subtract(s.PostedOn);
double daysAgo = elapsed.TotalDays;
return s.Votes.Count + s.Comments.Count - daysAgo;
}
这可能与 UDF 相关吗?
【问题讨论】:
标签:
asp.net
linq-to-sql
user-defined-functions
【解决方案1】:
可以,但是如果您使用的是 SQL Server 2000,则必须传入“now”的值——UDF 自身无法生成任何非确定性值in SQL Server 2000。
这个未经测试的尝试可能会接近:
CREATE FUNCTION dbo.GetStoryScore (
@Now DATETIME, @Posted DATETIME, @Votes INT, @Comments INT
) RETURNS FLOAT AS
BEGIN
RETURN @Votes + @Comments - DATEDIFF(HOUR, @Posted, @Now)/24.0
END
示例用法:
SELECT S.ID, dbo.GetStoryScore(GETDATE(), S.Posted, S.Votes, S.Comments) AS Score
FROM Stories AS S
WHERE ...
注意事项:
datediff 以小时(而不是天)为单位执行,因为当您使用更精细的单位时,整数结果会为您提供更高的精度。
我传入了所有值,因为我发现在函数中查找对性能来说非常非常糟糕。
在 SQL 中引用时,不要忘记函数名前的dbo.。
如果您使用的是 SQL Server 2005,则可以删除 @Now 变量并改为使用 GETDATE() 内联。
【解决方案2】:
我想像下面这样:
CREATE FUNCTION [dbo].[Score]
(@storyid int)
RETURNS float
AS
BEGIN
DECLARE @ret float;
DECLARE @elapsed float;
SELECT @elapsed = DATEDIFF(n, getdate(), postedon) / 1440
FROM stories WHERE storyid = @storyid;
SET @ret = ((SELECT count(voteid) FROM votes WHERE storyid = @storyid) +
(SELECT count(commentid) FROM comments WHERE storyid = @storyid) -
@elapsed);
RETURN @ret;
END