2011-12-12 152 views
0

我在这里拉我的头发。下面的函数总是返回null,即使它能正常工作,如果我将代码拖出到查询窗口并手动设置输入参数。这个想法是,我有一个基于月份的不同查询,因为每个月的平均值都存储在不同的列中。我知道,桌子的标准化程度不是很好,但这是我必须努力的。我错过了什么?SQL Server函数总是返回NULL

ALTER FUNCTION [dbo].[fn_currentShareBal] 
(
@currentDate datetime, 
@account  integer, 
@acctType  varchar 
) 
RETURNS money AS 
BEGIN 

DECLARE @dte char(10) 
DECLARE @returnVal money 
DECLARE @month int 

SET @dte = CONVERT(char(10), @currentDate, 101) 
SET @month = MONTH(@currentDate) 

-- because of the table strucure the actual query depends on the month 
IF @month = 1 SET @returnVal = (SELECT SUM(avg1) 
         FROM COSHAVG 
         WHERE cuID = @account 
         AND avgBalanceMonth = @dte 
         AND acctType = @acctType) 

IF @month = 2 SET @returnVal = (SELECT SUM(avg2) 
         FROM COSHAVG 
         WHERE cuID = @account 
         AND avgBalanceMonth = @dte 
         AND acctType = @acctType) 

IF @month = 3 SET @returnVal = (SELECT SUM(avg3) 
         FROM COSHAVG 
         WHERE cuID = @account 
         AND avgBalanceMonth = @dte 
         AND acctType = @acctType) 

IF @month = 4 SET @returnVal = (SELECT SUM(avg4) 
         FROM COSHAVG 
         WHERE cuID = @account 
         AND avgBalanceMonth = @dte 
         AND acctType = @acctType) 

IF @month = 5 SET @returnVal = (SELECT SUM(avg5) 
         FROM COSHAVG 
         WHERE cuID = @account 
         AND avgBalanceMonth = @dte 
         AND acctType = @acctType) 

IF @month = 6 SET @returnVal = (SELECT SUM(avg6) 
         FROM COSHAVG 
         WHERE cuID = @account 
         AND avgBalanceMonth = @dte 
         AND acctType = @acctType) 

IF @month = 7 SET @returnVal = (SELECT SUM(avg7) 
         FROM COSHAVG 
         WHERE cuID = @account 
         AND avgBalanceMonth = @dte 
         AND acctType = @acctType) 

IF @month = 8 SET @returnVal = (SELECT SUM(avg8) 
         FROM COSHAVG 
         WHERE cuID = @account 
         AND avgBalanceMonth = @dte 
         AND acctType = @acctType) 

IF @month = 9 SET @returnVal = (SELECT SUM(avg9) 
         FROM COSHAVG 
         WHERE cuID = @account 
         AND avgBalanceMonth = @dte 
         AND acctType = @acctType) 

IF @month = 10 SET @returnVal = (SELECT SUM(avg10) 
         FROM COSHAVG 
         WHERE cuID = @account 
         AND avgBalanceMonth = @dte 
         AND acctType = @acctType) 

IF @month = 11 SET @returnVal = (SELECT SUM(avg11) 
         FROM COSHAVG 
         WHERE cuID = @account 
         AND avgBalanceMonth = @dte 
         AND acctType = @acctType) 

IF @month = 12 SET @returnVal = (SELECT SUM(avg12) 
         FROM COSHAVG 
         WHERE cuID = @account 
         AND avgBalanceMonth = @dte 
         AND acctType = @acctType) 

RETURN @returnVal 

END 
GO 
+1

是'COSHAVG ''dbo'计划的一部分? – Glenn

+1

什么是avgBalanceMonth?将它与10个字符的日期故意相比较? – hatchet

+0

你是怎么调用这个函数的?你可能会考虑为你的输入参数设置默认值,看看是否改变了行为......如果你的话可能你的调用代码是行为不端...例如:在.NET中,内置解决方案可能会将NULL字符串转换为空白...只是一个想法 – Matthew

回答

1

我认为问题出在你的函数定义上。很难说因为你没有发布你的表的定义。

这是行不通的?如果没有,您可以在COSHAVG表上发布脚本创建吗?

ALTER FUNCTION [dbo].[fn_currentShareBal] 
(
    @currentDate datetime, 
    @account  integer, 
    @acctType  varchar(50) 
) 
RETURNS money 
AS 
BEGIN 
    DECLARE @dte varchar(20) 
    DECLARE @returnVal money 
    DECLARE @month int 

    SET @dte = CONVERT(varchar, @currentDate, 101) 
    SET @month = MONTH(@currentDate) 

    SELECT 
     @returnVal=SUM(CASE 
      WHEN @month = 1 THEN avg1 
      WHEN @month = 2 THEN avg2 
      WHEN @month = 3 THEN avg3 
      WHEN @month = 4 THEN avg4 
      WHEN @month = 5 THEN avg5 
      WHEN @month = 6 THEN avg6 
      WHEN @month = 7 THEN avg7 
      WHEN @month = 8 THEN avg8 
      WHEN @month = 9 THEN avg9 
      WHEN @month = 10 THEN avg10 
      WHEN @month = 11 THEN avg11 
      WHEN @month = 12 THEN avg12 
     END) 
    FROM COSHAVG 
    WHERE cuID = @account 
    AND avgBalanceMonth = @dte 
    AND acctType = @acctType 

    RETURN @returnVal 
END 
GO 
+0

这适用,正如Stuart下面几乎相同的代码一样。我不知道我可以使用这样的case语句来确定列,并且它更清晰。显然,Elroy在他上面的评论中头脑发热。当我在我的原始代码中将一个长度添加到varchar值时,它也可以工作。感谢大家。 – BeachBum

1

其他人所指出的事情,寻找在评论,但这里的重写功能(在行为没有真正改变,只是更容易保持)一个更清洁的方式:

ALTER FUNCTION [dbo].[fn_currentShareBal] 
    (
     @currentDate DATETIME 
    , @account INTEGER 
    , @acctType VARCHAR (100) 
    ) 
RETURNS MONEY 
AS 
    BEGIN 
     DECLARE @dte CHAR(10) 
     DECLARE @returnVal MONEY 
     DECLARE @month INT 
     SET @dte = CONVERT(CHAR(10), @currentDate, 101) 
     SET @month = MONTH(@currentDate) 
     -- because of the table strucure the actual query depends on the month 

     SELECT @returnVal = SUM(CASE WHEN @month = 1 THEN avg1 
             WHEN @month = 2 THEN avg2 
            /*...*/ 
             WHEN @month = 12 THEN avg12 
           END) 
     FROM COSHAVG 
     WHERE cuID = @account 
       AND avgBalanceMonth = @dte 
       AND acctType = @acctType 


     RETURN @returnVal 
    END 
+0

谢谢,斯图尔特。看起来SpectralGhost在大约3分钟之前发布了几乎相同的代码。希望我可以将两者都标记为答案。 – BeachBum