存储过程中的BETWEEN语句

时间:2011-02-26 08:59:25

标签: sql sql-server

我在SQL Server中有一个奇怪的例子。情况如下: 我有一个包含3列的表格:

ID  value1  value2
60FB    14.54   46.05
7066    12.18   41.23
7072    16.18   46.65
710F    12.17   47.65
7126    13.18   49.65
713E    17.18   48.65
7141    12.19   41.33
7144    12.18   47.65
7147    19.18   49.65
7149    18.18   42.65
71A6    17.18   43.65
71AA    14.54   44.05

ID为char,value1为decimal,value2为decimal。

如果我在SQL Server中执行select语句:

SELECT ID, value1, value2 
FROM         Node
where value1 between 12.1 and 12.2
and value2 between 41.2 and 41.5

我得到的结果就是我想要的结果:

ID  value1  value2
7066    12.18   41.23
7141    12.19   41.33

现在我想将between参数传递给存储过程,如下所示:

create procedure XYZ

@value1min decimal(2,5),
@value2min decimal(2,5),
@value1max decimal(2,5),
@value2max decimal(2,5)

AS
BEGIN

SELECT ID, value1, value2 
FROM         Node
where value1 between @value1min and @value1max
and value2 between @value2min and @value2max

当我使用相同的参数运行该过程时,我得到错误的结果:

ID  value1  value2
7066    12.18   41.23
710F    12.17   47.65
7141    12.19   41.33
7144    12.18   47.65

我认为问题在于value1,其中所有值都满足条件,但是这两个不满足value2范围的条件,所以我不知道为什么710F和7144出现在结果中。

有没有人对如何解决此问题有任何答案?

谢谢, 标记

2 个答案:

答案 0 :(得分:1)

您的DECIMAL定义混淆了:

decimal(2,5)

这意味着:我想要DECIMAL总共2位数 5 小数点分隔符。

您可能要定义的是:

decimal(7,5)

DECIMAL 总共7位数,其中5位小数点后分隔符(以及之前的2位)。

表格中的列是什么类型?

来自MSDN documentation for DECIMAL

  

十进制[(p [,s])]

     

修正了精度和刻度数。使用最大精度时,有效   值来自 - 10 ^ 38 +1到10 ^ 38 - 1.

     

p(精确度)

     

可以存储的最大小数位数,   在左边和右边   小数点。精度必须   是从1到最大值的值   精度为38.默认精度   是18岁。

     

s(比例)

     

可以存储到右侧的最大小数位数   小数点。比例必须是a   值从0到p。规模可以   仅在精度为时指定   指定。默认比例为0;   因此,0 <= s <= p。最大值   存储大小因人而异   精度。

答案 1 :(得分:1)

这更像是一个扩展的评论而不是一个答案:

为了善良,请不要过分简化这个问题

  1. 问题消失了
  2. proc甚至不是有效的语法
  3. 样本表

    create table node (ID char(4), value1 decimal(10,4), value2 decimal(10,4))
    insert node select
    '60FB' ,14.54  , 46.05 union all select
    '7066' ,12.18  , 41.23 union all select
    '7072' ,16.18  , 46.65 union all select
    '710F' ,12.17  , 47.65 union all select
    '7126' ,13.18  , 49.65 union all select
    '713E' ,17.18  , 48.65 union all select
    '7141' ,12.19  , 41.33 union all select
    '7144' ,12.18  , 47.65 union all select
    '7147' ,19.18  , 49.65 union all select
    '7149' ,18.18  , 42.65 union all select
    '71A6' ,17.18  , 43.65 union all select
    '71AA' ,14.54  , 44.05
    GO
    

    示例proc

    create procedure XYZ
    @value1min decimal(5,2),   --- << --- note here
    @value2min decimal(5,2),
    @value1max decimal(5,2),
    @value2max decimal(5,2)
    AS
    SELECT ID, value1, value2 
    FROM         Node
    where value1 between @value1min and @value1max
    and value2 between @value2min and @value2max
    GO
    

    选择使用固定值,然后是两个执行者。请注意,交换了第2和第3个参数

    select * from node
    where value1 between 12.1 and 12.2
    and value2 between 41.2 and 41.5
    ;
    exec xyz 12.1, 12.2, 41.2, 41.5
    ;
    exec xyz 12.1, 41.2, 12.2, 41.5
    

    每一个的情况下,输出为

    ID     value1    value2
    7066   12.1800   41.2300
    7141   12.1900   41.3300
    

    请注意

    • --- << --- note here如果您将参数更改为decimal(2,5),则会获得 Msg 192, Level 15, State 1, Procedure testme, Line 1. The scale must be less than or equal to the precision.
    • 如果你改为(7,5),那就没有区别了;适合(5,2)的数字将适合(7,5)。

    那么问题又出在哪里了?

    如果我完全猜测,那就是你将错误的参数传递给EXEC。