【问题标题】:How to compare a NUMBER with VARCHAR2 type number having leading zeroes?如何将 NUMBER 与具有前导零的 VARCHAR2 类型数字进行比较?
【发布时间】:2016-02-28 07:59:31
【问题描述】:

我正在尝试比较数据库中两个不同表中的两列。一列是 VARCHAR2(4 CHAR) 类型,另一列是 DECIMAL 类型。虽然我将这些列作为字符串拉入 JAVA 进行比较,但我遇到了这个问题:

列中的元素(十进制)为:123、456、789

比较列(varchar)的元素是:0123、0456、0789

所以我想知道是否有一种方法可以在我从数据库中提取它时删除这个前缀 0(比如某种 TRIM0()),这样两列中的元素会相同?

我试图避免在 JAVA 本身中处理此列以提高性能。

【问题讨论】:

  • 如果您比较两个整数,您的问题将得到解决。我建议你将 varchars 转移到 int
  • 我说的一样,在两个地方都使用相同的数字数据类型! LTRIM(列,'0')
  • @jarlh 在这里使用LTRIM 没有意义。字符串上的 LTRIM 将返回一个字符串。只需使用TO_NUMBER。

标签: sql oracle numbers type-conversion varchar


【解决方案1】:

您可以使用 LTRIM 从 varchar 数字中删除前导零:

select ltrim( '0001234', '0' ) from dual;

但我建议重新审视您的设计并将数字与数字进行比较。

【讨论】:

  • 要求是关于数据类型转换,而不是字符串操作。因此,您的答案并不能完全满足要求。一个字符串的LTRIM 将返回一个字符串。因此,您最终会将字符串与数字进行比较。依赖隐式数据类型转换是一种性能开销。您可以使用TO_NUMBER 一步完成。
【解决方案2】:

您可以尝试强制转换,但我相信这会损害查询的性能。如果一个字母中有一个字母,它可能会导致问题

where cast(column1 as unsigned) = cast(column2 as unsigned)

【讨论】:

  • 将其转换为数字的较短版本是使用TO_NUMBER。尽管您走在正确的轨道上,但主要要求是处理数据类型转换而不是字符串操作。
【解决方案3】:

(像某种 TRIM0())这样来自两列的元素会是相同的?

您的要求是关于数据类型转换,而不是字符串操作。

元素可能看起来相似,但重要的是数据类型。 '123' 和 123 不一样。它们看起来很相似,但它们是不同的数据类型。

不要使用 LTRIM,因为它会返回一个 STRING,您必须再次将其转换为 NUMBER 以避免 隐式数据类型转换。返回一个字符串,然后再次使用TO_NUMBER将其转换为数字是没有意义的。

正确有效的方法是使用TO_NUMBER。只需一步即可将其转换为 NUMBER。

例如,

SQL> SELECT to_number('00123') num FROM dual;

       NUM
----------
       123

SQL> SELECT * FROM dual WHERE to_number('00123') = 123;

D
-
X

附带说明,如果您确定总是需要列中的 NUMBER 来处理,那么您必须在 设计级别 修复它。将数字存储为字符类型是一种设计缺陷,除非有特定的业务需要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多