具有嵌入式SQL的SSRS中的递归UDF不准确

时间:2013-05-09 14:49:27

标签: sql-server reporting-services user-defined-functions

我正在报表设计器中创建报表。数据集使用如下查询:

SELECT LE.Amount, dbo.fnMoneyToEnglish(LE.Amount)
FROM tblXXX LE
WHERE LE.ID = @ID

UDF fnMoneyToEnglish应返回如下字样:

  

三十和00/100美元

但仅返回

  

第三

我怀疑这是因为UDF使用递归,调用自身。当我在SQL查询窗口中执行嵌入式SQL时,UDF返回完整的“Thirty and 00/100 Dollars”。它只是报表设计器有问题,只返回“三十”。我发现这很奇怪,因为我希望SSRS能够对数据库进行一次调用,UDF会执行并递归。

报表设计器是否以某种方式分解查询,是否仅限于对数据库的一次调用?

仅供参考,这是UDF:

ALTER FUNCTION [dbo].[fnMoneyToEnglish](@Money AS Money) 

RETURNS VARCHAR(1024)

AS

BEGIN
 DECLARE @Number as BIGINT
 DECLARE @MinusFlag as Bit

if @Money < 0
 begin
 set @Money = -1 * @Money
 Set @MinusFlag = 1
 end

SET @Number = FLOOR(@Money)

DECLARE @Below20 TABLE (ID int identity(0,1), Word varchar(32))

DECLARE @Below100 TABLE (ID int identity(2,1), Word varchar(32))

INSERT into @Below20 (Word) VALUES ( 'Zero')
 INSERT into @Below20 (Word) VALUES ('One')
 INSERT into @Below20 (Word) VALUES ('Two')
 INSERT into @Below20 (Word) VALUES ('Three')
 INSERT into @Below20 (Word) VALUES ('Four')
 INSERT into @Below20 (Word) VALUES ('Five')
 INSERT into @Below20 (Word) VALUES ('Six')
 INSERT into @Below20 (Word) VALUES ('Seven')
 INSERT into @Below20 (Word) VALUES ('Eight')
 INSERT into @Below20 (Word) VALUES ('Nine')
 INSERT into @Below20 (Word) VALUES ('Ten')
 INSERT into @Below20 (Word) VALUES ('Eleven')
 INSERT into @Below20 (Word) VALUES ('Twelve')
 INSERT into @Below20 (Word) VALUES ('Thirteen')
 INSERT into @Below20 (Word) VALUES ('Fourteen')
 INSERT into @Below20 (Word) VALUES ('Fifteen')
 INSERT into @Below20 (Word) VALUES ('Sixteen')
 INSERT into @Below20 (Word) VALUES ('Seventeen')
 INSERT into @Below20 (Word) VALUES ('Eighteen')
 INSERT into @Below20 (Word) VALUES ('Nineteen') 

INSERT into @Below100 (Word) VALUES ('Twenty')
 INSERT into @Below100 (Word) VALUES ('Thirty')
 INSERT into @Below100 (Word) VALUES ('Forty')
 INSERT into @Below100 (Word) VALUES ('Fifty')
 INSERT into @Below100 (Word) VALUES ('Sixty')
 INSERT into @Below100 (Word) VALUES ('Seventy')
 INSERT into @Below100 (Word) VALUES ('Eighty')
 INSERT into @Below100 (Word) VALUES ('Ninety') 

DECLARE @English varchar(1024)
 (
 SELECT @English =
 Case 

WHEN @Number = 0 THEN ''

WHEN @Number BETWEEN 1 AND 19 

THEN (SELECT Word FROM @Below20 WHERE ID=@Number)

WHEN @Number BETWEEN 20 AND 99

-- SQL Server recursive function 

THEN (SELECT Word FROM @Below100 WHERE ID=@Number/10)+ '-' +

dbo.fnMoneyToEnglish( @Number % 10) 

WHEN @Number BETWEEN 100 AND 999 

THEN (dbo.fnMoneyToEnglish( @Number / 100))+' Hundred '+

dbo.fnMoneyToEnglish( @Number % 100) 

WHEN @Number BETWEEN 1000 AND 999999 

THEN (dbo.fnMoneyToEnglish( @Number / 1000))+' Thousand '+

dbo.fnMoneyToEnglish( @Number % 1000) 

WHEN @Number BETWEEN 1000000 AND 999999999 

THEN (dbo.fnMoneyToEnglish( @Number / 1000000))+' Million '+

dbo.fnMoneyToEnglish( @Number % 1000000) 

WHEN @Number BETWEEN 1000000000 AND 999999999999 

THEN (dbo.fnMoneyToEnglish( @Number / 1000000000))+' Billion '+

dbo.fnMoneyToEnglish( @Number % 1000000000) 

ELSE ' INVALID INPUT' END

)

SELECT @English = RTRIM(@English)

SELECT @English = RTRIM(LEFT(@English,len(@English)-1))

WHERE RIGHT(@English,1)='-'

IF @@NestLevel = 1

BEGIN

SELECT @English = @English+' and '
SELECT @English = @English+
    convert(varchar, RIGHT('00'+ convert(varchar, convert(int,100*(@Money - @Number))),2)) +'/100 Dollars'
 if (@MinusFlag = 1)
 begin
 set @English = '( ' + @English + ' )'
 end

END

RETURN (@English)

END 

0 个答案:

没有答案