sql - 在 varchar 列中查找非数字值

标签 sql oracle oracle11g

要求:

通用查询/函数,用于检查表中 varchar 列中提供的值是否实际上是数字且精度不超过允许的精度。

可用值:

表名称、列名称、允许的精度、允许的小数位数

一般建议是创建一个函数并使用 to_number() 来验证该值,但它不会验证允许的长度(精度范围)。

我的解决方案:

使用正则表达式验证数字 NOT REGEXP_LIKE(COLUMN_NAME, '^-?[0-9.]+$')

验证左侧组件的长度(小数点之前)(我不知道它的实际名称是什么),因为对于比例,oracle 如果需要,会自动四舍五入。由于实际列是 varchar 我将使用 substr, instr 来查找小数点左侧的组件。

如上所述,正则表达式允许像 123...123124..55 这样的数字,我还将验证小数点的数量。 [如果 > 1 则错误]

查找无效号码的查询:

Select * From Table_Name 
Where
(NOT REGEXP_LIKE(COLUMN_NAME, '^-?[0-9.]+$')
OR
Function_To_Fetch_Left_Component(COLUMN_NAME) > (Precision-Scale)
/* Can use regexp_substr now but i already had a function for that */
OR
LENGTH(Column_Name) - LENGTH(REPLACE(Column_Name,'.','')) > 1
/* Can use regexp_count aswell*/)

我对我的解决方案感到高兴和满意,直到一列只有“.”。值(value)逃过了我的支票,我看到了我的支票的局限性。虽然添加另一个检查来验证这一点也可以解决我的问题,但整个解决方案对我来说效率很低。

我真的很感激[以任何方式]更好的解决方案。

提前致谢。

最佳答案

寻找:

  • 一个或多个数字(可选)后跟小数点和零个或多个数字;或
  • 一个前导小数点(前面没有单位数字),然后是一个或多个(小数)数字。

像这样:

Select *
From   Table_Name 
Where  NOT REGEXP_LIKE(COLUMN_NAME, '^[+-]?(\d+(\.\d*)?|\.\d+)$')

如果您不想在数字字符串中使用零填充值,则:

Select *
From   Table_Name 
Where  NOT REGEXP_LIKE(COLUMN_NAME, '^[+-]?(([1-9]\d*|0)(\.\d*)?|\.\d+)$')

具有精度和小数位数(假设它按照 NUMBER( precision, scale ) 数据类型和 scale < precision 工作):

Select *
From   Table_Name 
Where  NOT REGEXP_LIKE(COLUMN_NAME, '^[+-]?(\d{1,'||(precision-scale)||'}(\.\d{0,'||scale||'})?|\.\d{1,'||scale||'})$')

或者,对于具有精度和小数位数的非零填充数字:

Select *
From   Table_Name 
Where  NOT REGEXP_LIKE(COLUMN_NAME, '^[+-]?(([1-9]\d{0,'||(precision-scale-1)||'}|0)(\.\d{0,'||scale||'})?|\.\d{1,'||scale||'})$')

或者,对于任何精度和比例:

Select *
From   Table_Name 
Where  NOT REGEXP_LIKE(
             COLUMN_NAME,
             CASE
               WHEN scale <= 0
               THEN '^[+-]?(\d{1,'||precision||'}0{'||(-scale)||'})$'
               WHEN scale < precision
               THEN '^[+-]?(\d{1,'||(precision-scale)||'}(\.\d{0,'||scale||'})?|\.\d{1,'||scale||'})$'
               WHEN scale >= precision
               THEN '^[+-]?(0(\.0{0,'||scale||'})?|0?\.0{'||(scale-precision)||'}\d{1,'||precision||'})$'
             END
           )

关于sql - 在 varchar 列中查找非数字值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47711667/

相关文章:

ubuntu - 删除在安装 oracle 11g 时创建的符号链接(symbolic link)/usr/bin/awk/bin/awk

sql - 设计一个表来存储 EXIF 数据

sql - Oracle SQL 按多个 OR 条件进行分组

java - SQL 查询可以在 SQL Developer 中运行,但不能在 Java 端运行

SQL ORACLE ORA-00969 : missing ON keyword?

linux - 使用 Oracle Instant Client Docker 镜像时出错

oracle - 如何在对象之前不预先固定架构名称的情况下由多个用户使用一个架构?

mysql - SQL:计算(并填充?)有序结果之间的差异

sql - 删除超过一定长度的字符串中的空格

mysql - 如何获取具有左连接的行与两个右表行匹配MySQL中的两个单独的值?