我正在尝试创建此功能。当我解析它时,它工作正常,但实际上在数据库中创建函数它说我的列名无效。事实并非如此,我拼写正确。这是代码:
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
答案 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标准的标点符号(用分号终止语句),并且省略多余的开头/结尾 - 这对于作为测试结果执行的单语句行不需要这些也会有所帮助。