Oracle regexp_like FLOAT 从视图中失败
Oracle regexp_like failing on FLOAT from view
我正在尝试使用 regexp_like 查找和删除过于精确的浮点数。
select c from t order by c asc;
returns 许多这样的结果:0.0000000012345678
使用 regexp_like 我可以获得两位小数 (0.25) 的结果:
select * from t where REGEXP_LIKE(c,'^\d+\.\d{2}');
但是,当我尝试两个以上的地方时,我没有得到任何结果:
select * from t where REGEXP_LIKE(c,'^\d+\.\d{3}');
...
select * from t where REGEXP_LIKE(c,'^\d+\.\d{10}');
唯一的附加信息是我正在选择第二个视图的视图,并且我正在搜索的列(c,上面)被指定为 FLOAT。
您可以将它们视为数字。您可以truncate将数值保留到固定的小数位数:
The TRUNC
(number) function returns n1 truncated to n2 decimal places.
然后看是否匹配。例如,要查找小数点后有效数字超过 2 位的任何值:
select * from t where c != trunc(c, 2);
或查找有效数字超过10位的:
select * from t where c != trunc(c, 10);
如果你有负值,我使用 !=
而不是 >
。
您还可以将其用作 delete/update 中的过滤器,或者如果您想降低精度,则将其用作更新的 set
部分 - 尽管在这种情况下您可能想要使用round()
而不是 trunc()
.
当您使用 regexp_like
时,您正在将浮点值隐式转换为字符串,如 the docs for to_char()
注意:
If you omit fmt, then n is converted to a VARCHAR2
value exactly long enough to hold its significant digits.
这意味着 0.25 成为字符串 '.25'
,没有前导零;这甚至与您的第一个模式都不匹配。
您可以通过使用 *
而不是 +
来允许前导零不存在,例如查找小数点后至少有 10 位有效数字的值:
select * from t where REGEXP_LIKE(c,'^\d*\.\d{10}');
或正好 10:
select * from t where REGEXP_LIKE(c,'^\d*\.\d{10}$');
等;但将它们视为数字而不是字符串似乎更简单。
我正在尝试使用 regexp_like 查找和删除过于精确的浮点数。
select c from t order by c asc;
returns 许多这样的结果:0.0000000012345678
使用 regexp_like 我可以获得两位小数 (0.25) 的结果:
select * from t where REGEXP_LIKE(c,'^\d+\.\d{2}');
但是,当我尝试两个以上的地方时,我没有得到任何结果:
select * from t where REGEXP_LIKE(c,'^\d+\.\d{3}');
...
select * from t where REGEXP_LIKE(c,'^\d+\.\d{10}');
唯一的附加信息是我正在选择第二个视图的视图,并且我正在搜索的列(c,上面)被指定为 FLOAT。
您可以将它们视为数字。您可以truncate将数值保留到固定的小数位数:
The
TRUNC
(number) function returns n1 truncated to n2 decimal places.
然后看是否匹配。例如,要查找小数点后有效数字超过 2 位的任何值:
select * from t where c != trunc(c, 2);
或查找有效数字超过10位的:
select * from t where c != trunc(c, 10);
如果你有负值,我使用 !=
而不是 >
。
您还可以将其用作 delete/update 中的过滤器,或者如果您想降低精度,则将其用作更新的 set
部分 - 尽管在这种情况下您可能想要使用round()
而不是 trunc()
.
当您使用 regexp_like
时,您正在将浮点值隐式转换为字符串,如 the docs for to_char()
注意:
If you omit fmt, then n is converted to a
VARCHAR2
value exactly long enough to hold its significant digits.
这意味着 0.25 成为字符串 '.25'
,没有前导零;这甚至与您的第一个模式都不匹配。
您可以通过使用 *
而不是 +
来允许前导零不存在,例如查找小数点后至少有 10 位有效数字的值:
select * from t where REGEXP_LIKE(c,'^\d*\.\d{10}');
或正好 10:
select * from t where REGEXP_LIKE(c,'^\d*\.\d{10}$');
等;但将它们视为数字而不是字符串似乎更简单。