Я, вероятно, должен упомянуть, что скалярные UDF-сообщения действительно сопровождаются значительным предупреждением о вреде для здоровья и могут вызвать проблемы с производительностью в зависимости от того, как вы их используете.
Вот пример.
CREATE FUNCTION dbo.Funname ( @param INT )
RETURNS INT
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
RETURN (SELECT number FROM master.dbo.spt_values WHERE number < @param)
END
В приведенном выше примере я не использовал переменную, поскольку она избыточна. Версия с переменной -
BEGIN
DECLARE @Result int
SET @Result = (SELECT number FROM master.dbo.spt_values WHERE number < @param)
RETURN @Result
END
Для обоих вышеперечисленных случаев вы должны быть уверены, что запрос вернул не более одной строки, чтобы избежать ошибки во время выполнения. Например
select dbo.Funname(-1)
Возвращает -32768
select dbo.Funname(0)
Возвращает ошибку «Подзапрос возвратил более 1 значения.»
Альтернативный синтаксис будет
BEGIN
DECLARE @Result int
SELECT @Result = number FROM master.dbo.spt_values WHERE number < @param
RETURN @Result
END
Это больше не вызовет ошибку, если подзапрос вернул более одного значения, но вы просто получите произвольный результат без предупреждения - что еще хуже.
После комментариев Я думаю, что это то, что вам нужно
CREATE FUNCTION dbo.getcustgrade(@custid CHAR(200))
RETURNS INT
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
RETURN
( SELECT [cust grade]
FROM ( SELECT customerid,
DENSE_RANK() OVER (ORDER BY COUNT(*) DESC) AS [cust grade]
FROM Orders
GROUP BY CustomerID
)
d
WHERE customerid = @custid
)
END