带参数的SQL Server函数

时间:2017-02-16 21:06:12

标签: sql-server

我正在创建一个SQL Server函数

ALTER function [dbo].[GetAbnormalProductionHourFlag]
    (@startDate date, 
     @endDate date, 
     @employeeId integer, 
     @lowBand decimal, 
     @highBand decimal) 
returns integer
as
begin
    declare @flagCount integer

    set @flagCount = (select count(*) 
                      from AHFAB_vTimecardLines
                      where lmlActualStartTime >= @startDate
                        and (lmlActualEndTime < @endDate or lmlActualEndTime is null)
                        and lmlEmployeeID = @employeeId
                        and (jmoActualProductionHours < @lowBand or jmoActualProductionHours > @highBand))

    return @flagCount

并调用函数

select dbo.GetAbnormalProductionHourFlag1('2017/02/01', '2017/02/17', 5124, 0.10, 3.00)

当我尝试调试时,由于某种原因,监视列表SQL调试器上@lowBand的值被传递为0,而不是0.1

是否有一种将十进制值参数传递给SQL Server函数的特殊方法?

我很困惑,我认为通过在参数类型上设置十进制,它应该传递正确的值。

如果你能说清楚我错过的或者我做错了,我将不胜感激。

3 个答案:

答案 0 :(得分:1)

decimal的默认值为decimal(18,0),表示0位小数。您必须明确地提供精确度和比例,如decimal(18,9)

这描述为here on msdn

答案 1 :(得分:1)

更好的是,将其重写为内联表值函数

create function [dbo].[GetAbnormalProductionHourFlag_inline] (
    @startDate date
  , @endDate date
  , @employeeId integer
  , @lowBand decimal(19,6)
  , @highBand decimal(19,6)
) 
returns table as return (
  select FlagCount = count(*) 
  from AHFAB_vTimecardLines
  where lmlActualStartTime >= @startDate
    and (lmlActualEndTime < @endDate 
        or lmlActualEndTime is null)
    and lmlEmployeeID = @employeeId
    and (jmoActualProductionHours < @lowBand 
        or jmoActualProductionHours > @highBand)
);
go

select FlagCount 
from dbo.GetAbnormalProductionHourFlag_inline('2017/02/01', '2017/02/17', 5124, 0.10, 3.00)

参考:

答案 2 :(得分:0)

将@lowBand重新定义为float。

ALTER function [dbo].[GetAbnormalProductionHourFlag]
(@startDate date, 
 @endDate date, 
 @employeeId integer, 
 @lowBand float, 
 @highBand float) 
 returns integer
 as
begin
declare @flagCount integer

set @flagCount = (select count(*) 
                  from AHFAB_vTimecardLines
                  where lmlActualStartTime >= @startDate
                    and (lmlActualEndTime < @endDate or lmlActualEndTime is null)
                    and lmlEmployeeID = @employeeId
                    and (jmoActualProductionHours < @lowBand or jmoActualProductionHours > @highBand))

return @flagCount