Если Else If In Sql Server Function
У меня есть эта функция, которую я пытаюсь создать. Когда я разбираю его, он работает нормально, но для фактического создания функции в базе данных он говорит, что мои имена столбцов недействительны. Это неверно, я правильно их написал. Вот код:
ALTER FUNCTION [dbo].[fnTally] (@SchoolId nvarchar(50))
RETURNS int
AS
BEGIN
DECLARE @Final nvarchar
IF EXISTS (
SELECT
question,
yes_ans,
no_ans,
na_ans,
blank_ans
FROM dbo.qrc_maintally
WHERE school_id = @SchoolId
)
IF yes_ans > no_ans AND yes_ans > na_ans
BEGIN
SET @Final = 'Yes'
END
ELSE IF no_ans > yes_ans AND no_ans > na_ans
BEGIN
SET @Final = 'No'
END
ELSE IF na_ans > yes_ans AND na_ans > no_ans
BEGIN
SET @Final = 'N/A'
END
RETURN @Final
END
Ответы
Ответ 1
Вам нужно будет создать локальные переменные для этих столбцов, назначить их во время выбора и использовать их для ваших условных тестов.
declare @yes_ans int,
@no_ans int,
@na_ans int
SELECT @yes_ans = yes_ans, @no_ans = no_ans, @na_ans = na_ans
from dbo.qrc_maintally
where school_id = @SchoolId
If @yes_ans > @no_ans and @yes_ans > @na_ans
begin
Set @Final = 'Yes'
end
-- etc.
Ответ 2
ALTER FUNCTION [dbo].[fnTally] (@SchoolId nvarchar(50))
RETURNS nvarchar(3)
AS BEGIN
DECLARE @Final nvarchar(3)
SELECT @Final = CASE
WHEN yes_ans > no_ans AND yes_ans > na_ans THEN 'Yes'
WHEN no_ans > yes_ans AND no_ans > na_ans THEN 'No'
WHEN na_ans > yes_ans AND na_ans > no_ans THEN 'N/A' END
FROM dbo.qrc_maintally
WHERE school_id = @SchoolId
Return @Final
End
Как вы можете видеть, это значительно упрощает код. Это также делает другие ошибки в коде более очевидными: вы возвращаете nvarchar, но объявили функцию для возврата int (исправлено в коде выше).
Ответ 3
Никто, кажется, не выбрал, что если (yes = no) > na или (no = na) > yes или (na = yes) > no, вы получите NULL в качестве результата. Не верьте, что это то, что вам нужно.
Здесь также более сжатая форма функции, которая работает , даже если любая из да, no или na_ans - NULL.
USE [***]
GO
/****** Object: UserDefinedFunction [dbo].[fnActionSq] Script Date: 02/17/2011 10:21:47 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[fnTally] (@SchoolId nvarchar(50))
RETURNS nvarchar(3)
AS
BEGIN
return (select (
select top 1 Result from
(select 'Yes' Result, yes_ans union all
select 'No', no_ans union all
select 'N/A', na_ans) [ ]
order by yes_ans desc, Result desc)
from dbo.qrc_maintally
where school_id = @SchoolId)
End
Ответ 4
If yes_ans > no_ans and yes_ans > na_ans
Вы используете имена столбцов в инструкции (вне запроса). Если вы хотите переменные, вы должны объявить и назначить их.
Ответ 5
Посмотрите на эти строки:
Если yes_ans > no_ans и yes_ans > na_ans
и тому подобное. К чему относятся "yes_ans" и т.д.? Вы не используете их в контексте запроса; условие "если существует" не распространяется на имена столбцов, которые вы используете внутри.
Рассмотрите возможность назначения этих значений переменным, которые вы затем можете использовать для своего условного потока ниже. Таким образом,
if exists (some record)
begin
set @var = column, @var2 = column2, ...
if (@var1 > @var2)
-- do something
конец
Тип возврата также несовместим с объявлением. Это сильно помогло бы вам, если бы вы отступали, использовали стандартную пунктуацию ANSI (завершать операторы с точкой с запятой) и оставляли лишнее начало/конец - вам не нужны эти строки для строк с одной строкой, выполненные в результате теста.
Ответ 6
Я думаю, вам будет лучше с CASE-оператором, который работает намного больше, чем IF/ELSEIF
DECLARE @this int, @value varchar(10)
SET @this = 200
SET @value = (
SELECT
CASE
WHEN @this between 5 and 10 THEN 'foo'
WHEN @this between 10 and 15 THEN 'bar'
WHEN @this < 0 THEN 'barfoo'
ELSE 'foofoo'
END
)
Дополнительная информация: http://technet.microsoft.com/en-us/library/ms181765.aspx