2011-12-12 151 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