2017-05-03 66 views
0

我在帮助同事调试返回奇怪结果的查询。我们把范围缩小到一条线,是这样的:了解ORACLE'S BETWEEN关键字

WHERE COL BETWEEN“11201”和“111226”

在COL的价值来自于子打电话,所以这是一个字符串类型的值。这不会返回结果。天真地,我一直认为BETWEEN代表> =和< =,如果你用字符串调用它,它会把所有东西都转换成数值类型值。这工作得很好,如果你有这样的:

WHERE COL BETWEEN“11201”和“11226”

在哪,我们都在使用它的情况下返回结果。

显然,由于第二段代码返回了结果,但第一段代码没有,我的理解是错误的。

我把所有东西都转换成了数字,然后再次尝试,并得到了预期的行为。由此看来,我可以得出结论,当它进行字符串比较时,实际上不会转换值 - 相反,它逐个字符地转换。当它到达第三个字符并且在下限参数中看到2> 1时,它将基于以下行为从Oracle documents退出:

如果expr3 < expr2,则间隔为空。

任何人都可以权衡如果这是真正发生在引擎盖下的事情吗?

谢谢!

+1

'col'是一个字符串,你传递两个字符串成' between'。我不知道你为什么会期望这样做,但是,正如你注意到的那样,它不会。 – Donnie

+0

@Donnie是的,我真的不知道为什么我会认为它会施展 - 回想起来似乎很愚蠢。 – Joe

回答

4

表达:

WHERE COL BETWEEN '11201' AND '111226' 

是一样的:

WHERE COL >= '11201' AND COL <= '111226' 

这没有返回,因为 - 作为字符串 - '11201'> '111226'。这将使用字母排序,因此,如果您使用的字母,这将是更清楚:

WHERE COL BETWEEN 'BBCAB' AND 'BBBCCG' 

显然,没有任何这些值之间的字母,因为'BBC''BBB'后发生

道德?如果你想比较直观,使用正确的类型。

+0

这与我在测试后在问题的下半部分推测的内容相符,所以我会将其标记为接受的答案。 – Joe

+0

@Joe - Gordon回复结束时的“道德”值得多于黄金的重量。这意味着什么不是“在TO_NUMBER中包装COL”。相反,它的意思是“让COL成为NUMBER数据类型的列”。这件事情是由很多原因导致的。例如,如果您在COL上有一个索引,并且您的意思是COL是数字型的,但是您将其声明为字符串,则将无法使用该索引 - 因此,应该几乎是瞬间的查询可能会运行几分钟。错误的数据类型可能是Oracle(以及一般编程)中最常见的滥用。 – mathguy

2

在表达低于

WHERE COL BETWEEN '11201' AND '111226' 

您对文本比较文本列COL。字符串'11201'按字典顺序大于字符串'111226'。换句话说,'11201'来到'111226'在字典中,或前者是大于比后者。这就是为什么没有结果回来。但是,如果你投COL到一个号码,比较,为数字,则比较可能工作,假设有匹配的记录:

WHERE TO_NUMBER(COL) BETWEEN 11201 AND 111226