高效查询以查找varchar列中的无效数字

时间:2017-12-10 09:49:10

标签: oracle oracle11g

我之前已经问了几乎相同的问题: Finding non-numeric values in varchar column

我收到了一些很好的答案和想法,不仅可以解决我的查询中的问题,还可以提高效率。

旧查询:

Select * From Table_Name 
Where
(NOT REGEXP_LIKE(COLUMN_NAME, '^-?[0-9.]+$')
OR
LENGTH(Function_To_Fetch_Left_Component(COLUMN_NAME)) > (Precision-Scale)
OR
LENGTH(Column_Name) - LENGTH(REPLACE(Column_Name,'.','')) > 1)

新查询:

Select * From Table_Name
WHERE (Translate(column_name,'x0123456789-.','x') is not null
OR column_name = '.'
OR column_name = '-'
OR column_name = '-.'
OR Instr(column_name,'-') > 1
OR column_name like '%-%-%'
OR column_name like '%.%.%'
OR Instr(column_name||'.','.')-1 > (precision-scale)  )  ;

已知的限制是可以的:

1。)不处理科学记数法。它的设计因为我想拒绝那些。

2。)不检查总精度(十进制分量)但是当插入oracle本身时它会关闭它我没关系。

3.)不检查前导零。

请帮助查看以上查询是否涵盖了所有内容,而且我没有遗漏任何内容。

Stackoverflow成员的另一个出色解决方案是将执行时间增加了2.5倍:

功能:

CREATE OR REPLACE function temp_is_number(p_test_value varchar2,
                                     p_scale NUMBER,
                                     p_precision NUMBER) return varchar2  is

  l_result varchar2(1);
begin
  execute immediate 'DECLARE l_number NUMBER; ' ||
                    'l_test_number NUMBER(' || p_precision || ',' || p_scale || '); ' ||
                    'BEGIN ' ||
                    '  l_number := cast(:b1 as number); ' ||
                    '  l_test_number := cast(:b1 as number); ' ||
                    '  IF (l_number = l_test_number) THEN ' ||
                    '    :b2 := ''Y''; ' ||
                    '  ELSE ' ||
                    '    :b2 := ''N''; ' ||
                    '  END IF; ' ||
                    'EXCEPTION ' ||
                    '  WHEN OTHERS THEN ' ||
                    '    :b2 := ''N''; ' ||
                    'END;'
        using in p_test_value, out l_result;
  return l_result;
end;
/

Select Count(1) from Table_Name Where temp_is_number (Column_Name,scale,precision) = 'N';

0 个答案:

没有答案