【问题标题】:SQL ORACLE : Is it possible to convert NUMBER with CHAR (varchar2 datatype) to NUMBER datatypeSQL ORACLE:是否可以将带有 CHAR(varchar2 数据类型)的 NUMBER 转换为 NUMBER 数据类型
【发布时间】:2021-04-28 13:07:39
【问题描述】:

我现在有一个大问题,我真的需要你的帮助,因为我找不到正确的答案。 我目前正在编写一个脚本,该脚本触发从包含原始数据(我们从 excel 文件接收的数据)的表到新的规范化架构的迁移过程。

我的问题是有一列 PRICE(varchar2 数据类型)带有一堆 陷阱。例如:540S、25ooI200、S000。

我需要将其转换为正确的 NUMBER(9,2) 格式,这样我才能得到: 5405, 2500, 1200, 5000 作为前面示例的 NUMBER 和 INSERT INTO my_new_table

有什么方法可以解析这些字符串中的每个 CHAR 来验证某些条件? 或者其他更好的方法?

谢谢你:)!

【问题讨论】:

  • 请解释一下规则。为什么忽略'S' 而将'I' 视为'1'
  • 我没有忽略S。我犯了一个错误对不起:(。
  • 我已经编辑了我的帖子
  • 您的输入中能否包含任何其他字符 - 不是数字占位符的字符?我知道'o' 的意思是零;如果数字中间有'h' 之类的东西怎么办?您是否希望转换为数字失败,以便您有机会查看该特定数字并决定如何处理它? (或者,更好的是,询问您的用户,以便他们决定如何处理?)

标签: sql oracle


【解决方案1】:

您可以使用translate()to_number()。你的规则不是很清楚,但是是这样的:

select to_number(translate(price, '0123456789IoS', '012345678910'))
from t;

这会将I 替换为1,将o 替换为0,并删除S

【讨论】:

  • 谢谢!我会试试看,我会告诉你它是否有效
  • 你的方法奏效了!非常感谢 :)。我也会检查答案。
  • 为什么需要翻译数字(自己)?那只是在没有真正目的的情况下浪费时间。 translate() 应该只将非数字转换为正确的数字。
  • 我会接受@Caius Jard 作为答案,因为它总结了函数的所有方面。但是谢谢你的反应:)
  • @CaiusJard - 这不是唯一一次。在这个问题中,假设 OP 想要翻译一些字母并删除其他字母(如在您的示例中,但事先不知道可能存在哪些其他字符 - 字母或其他字符)。然后你可以translate(number, '01234567890SsIilOo' || number, '01234567895511100')。这就是为什么我要求 OP 进行澄清(在他原始问题下方的评论中)。
【解决方案2】:

其他一些数据库所缺乏的关于 Oracle 的优点之一就是 TRANSLATE 功能:

SELECT TRANSLATE(number, 'SsIilOoxyz', '5511100') FROM t

这将转换:

S, s to 5
I, i and l to 1
O, o to 0
Remove any x, y or z from the number

translate 的第二个和第三个参数定义了要映射的字符。如果第一个字符串比第二个长,则从结果字符串中删除超过第二个长度的任何内容。映射直接基于位置:

'SsIilOoxyz', 
'5511100'

查看字符的列;上面的字符映射到下面的字符:

S->5, 
s->5, 
I->1, 
i->1, 
l->1, 
O->0, 
o->0,
x->removed, 
y->removed, 
z->removed`

【讨论】:

  • 谢谢!这是完全正确的答案。
  • @Dim433 另一个有用的东西可以使用 translate列值中存在的所有无效字符的结果,因此您可以为它们设计替换
  • Postgres 也有一个translate() 函数。
  • @a_horse_with_no_name mm.. SQLS 也是如此,但仅在 2017 年(Oracle 之后大约 20 年!)并且字符串必须具有相同的长度,因此不太有用..
猜你喜欢
  • 2016-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-06
  • 1970-01-01
  • 2023-03-29
相关资源
最近更新 更多