Как написать пользовательскую функцию? - PullRequest
1 голос
/ 15 января 2009

Я хотел бы написать это как пользовательскую функцию:

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?

Ответы [ 2 ]

2 голосов
/ 15 января 2009

Можно, но если вы используете SQL Server 2000, вам придется передать значение "сейчас" - пользовательские функции не могут сами генерировать недетерминированные значения в 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 ...

Примечания:

  • Дата выполняется в часах (не днях), потому что целочисленный результат дает вам немного большую точность при использовании более мелких единиц.

  • Я передал все значения, потому что я нашел, что поиск в функциях очень, очень плохо влияет на производительность.

  • При ссылке в SQL не забывайте dbo. перед именем функции.

  • Если вы используете SQL Server 2005, вы можете удалить переменную @Now и использовать вместо нее встроенный метод GETDATE ().

0 голосов
/ 15 января 2009

Что-то похожее на следующее, которое я себе представляю:

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
...