如果在Sql Server函数中也是如此

时间:2011-02-17 16:35:20

标签: sql sql-server-2005

我正在尝试创建此功能。当我解析它时,它工作正常,但实际上在数据库中创建函数它说我的列名无效。事实并非如此,我拼写正确。这是代码:

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

6 个答案:

答案 0 :(得分:9)

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(在上面的代码中已更正)。

答案 1 :(得分:7)

您需要为这些列创建局部变量,在选择期间分配它们并将它们用于条件测试。

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 :(得分:3)

似乎没有人选择if(yes = no)> na或(no = na)> yes或(na = yes)> no,结果为NULL。不要相信这就是你所追求的。

这里也是一个更精简的函数形式,即使任何yes,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

答案 3 :(得分:2)

If yes_ans > no_ans and yes_ans > na_ans  

您在语句中使用列名(在查询之外)。如果你想要变量,你必须声明并分配它们。

答案 4 :(得分:2)

我认为你最好使用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

答案 5 :(得分:0)

看看以下几行:

if yes_ans&gt; no_ans和yes_ans&gt; na_ans

和类似的。 “yes_ans”等指的是什么?您没有在查询的上下文中使用它们; “if exists”条件不会扩展到您在内部使用的列名。

考虑将这些值分配给您可以在下面用于条件流的变量。因此,

if exists (some record)
begin
   set @var = column, @var2 = column2, ...

   if (@var1 > @var2)
      -- do something

返回类型也与声明不匹配。如果你缩进,使用ANSI标准的标点符号(用分号终止语句),并且省略多余的开头/结尾 - 这对于作为测试结果执行的单语句行不需要这些也会有所帮助。