Подтвердить что ты не робот

Если 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
4b9b3361

Ответ 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