sqoop导入作业失败的原因:java.sql.sqlexception:数值溢出我必须加载oracle表,它在oracle中具有列类型编号,没有缩放,并且在配置单元中转换为双精度。这是oracle和hive数值的最大可能大小。问题是如何克服这个错误?
weylhg0b1#
edit:这个答案假设您的oracle数据是好的,并且您的sqoop作业需要特定的配置来处理数值。事实并非如此,请参阅另一个答案。理论上是可以解决的。在oracle文档中,关于“将oracle表复制到hadoop”(在他们的大数据设备中),“创建配置单元表”>“关于数据类型转换”。。。数当刻度为0且精度小于10时为int当刻度为0且精度小于19时为bigint小数位数大于0或精度大于19因此,必须找出oracle表中的实际值范围,然后才能指定目标配置单元列 BIGINT 或者 DECIMAL(38,0) 或者 DECIMAL(22,7) 或者别的什么。现在,从关于“sqoop-import”>“控制类型Map”的sqoop文档中。。。sqoop被预先配置为将大多数sql类型Map到适当的java或hive代表。但是,默认Map可能不适合所有人,可能会被 --map-column-java (用于将Map更改为java)或 --map-column-hive (用于更改配置单元Map)。例如,sqoop需要逗号分隔的Map列表(…) $ sqoop import ... --map-column-java id=String,value=Integer 注意事项1:根据sqoop-2103,您需要sqoop v1.4.7或更高版本才能使用带小数的选项,并且需要对逗号进行“url编码”,例如DECIMAL(22,7) --map-column-hive "wtf=Decimal(22%2C7)" 警告2:在您的例子中,不清楚溢出是在将oracle值读入java变量时发生的,还是在将java变量写入hdfs文件时发生的,甚至是在其他地方。所以也许 --map-column-hive 这是不够的。同样,根据指向sqoop-1493的帖子, --map-column-java 不支持java类型 java.math.BigDecimal 至少在sqoopv1.4.7之前(现在还不清楚这个特定的选项是否支持它,以及它是否被预期为 BigDecimal 或者 java.math.BigDecimal )实际上,由于sqoop1.4.7并非在所有发行版中都可用,而且由于您的问题没有得到很好的诊断,所以它可能不可行。因此,我建议您在读取时通过将rogue oracle列转换为字符串来隐藏问题。请参阅有关“sqoop-import”>“自由形式查询导入”的文档。。。而不是使用 --table , --columns 以及 --where 参数,您可以使用 --query 参数(…)您的查询必须包含标记$conditions(…),例如: $ sqoop import --query 'SELECT a.*, b.* FROM a JOIN b ON a.id=b.id WHERE $CONDITIONS' ... 就你而言, SELECT x, y, TO_CHAR(z) AS z FROM wtf 加上\u char中的适当格式,这样您就不会因为舍入而丢失任何信息。
BIGINT
DECIMAL(38,0)
DECIMAL(22,7)
--map-column-java
--map-column-hive
$ sqoop import ... --map-column-java id=String,value=Integer
--map-column-hive "wtf=Decimal(22%2C7)"
java.math.BigDecimal
BigDecimal
--table
--columns
--where
--query
$ sqoop import --query 'SELECT a.*, b.* FROM a JOIN b ON a.id=b.id WHERE $CONDITIONS' ...
SELECT x, y, TO_CHAR(z) AS z FROM wtf
jvlzgdj92#
好的,我的第一个答案假设您的oracle数据是好的,而您的sqoop作业需要特定的配置来处理数值。但现在我怀疑你的甲骨文数据里有狗屎,特别是 NaN 值,作为计算错误的结果。请参阅以下文章:oracle何时/为什么向数据库表中的行添加nan而甲骨文甚至有明显的“非数字”类别来表示“无限”,使事情更加复杂。但在 java 方面, BigDecimal 不支持 NaN --从文档中,在所有转换方法中。。。抛出: NumberFormatException -如果值为无穷大或nan。请注意,jdbc驱动程序会屏蔽该异常并显示 NumericOverflow 相反,为了使调试更加复杂。。。所以你的问题看起来是这样的:solr numeric overflow(来自oracle)--但不幸的是solr允许跳过错误,而sqoop则不允许;所以你不能用同样的伎俩。最后,你将不得不“掩盖”这些 NaN 具有oracle函数的值 NaNVL ,使用sqoop中的自由形式查询:
NaN
NumberFormatException
NumericOverflow
NaNVL
$ sqoop import --query 'SELECT x, y, NANVL(z, Null) AS z FROM wtf WHERE $CONDITIONS'
2条答案
按热度按时间weylhg0b1#
edit:这个答案假设您的oracle数据是好的,并且您的sqoop作业需要特定的配置来处理数值。事实并非如此,请参阅另一个答案。
理论上是可以解决的。
在oracle文档中,关于“将oracle表复制到hadoop”(在他们的大数据设备中),“创建配置单元表”>“关于数据类型转换”。。。
数
当刻度为0且精度小于10时为int
当刻度为0且精度小于19时为bigint
小数位数大于0或精度大于19
因此,必须找出oracle表中的实际值范围,然后才能指定目标配置单元列
BIGINT
或者DECIMAL(38,0)
或者DECIMAL(22,7)
或者别的什么。现在,从关于“sqoop-import”>“控制类型Map”的sqoop文档中。。。
sqoop被预先配置为将大多数sql类型Map到适当的java或hive代表。但是,默认Map可能不适合所有人,可能会被
--map-column-java
(用于将Map更改为java)或--map-column-hive
(用于更改配置单元Map)。例如,sqoop需要逗号分隔的Map列表(…)
$ sqoop import ... --map-column-java id=String,value=Integer
注意事项1:根据sqoop-2103,您需要sqoop v1.4.7或更高版本才能使用带小数的选项,并且需要对逗号进行“url编码”,例如DECIMAL(22,7)
--map-column-hive "wtf=Decimal(22%2C7)"
警告2:在您的例子中,不清楚溢出是在将oracle值读入java变量时发生的,还是在将java变量写入hdfs文件时发生的,甚至是在其他地方。所以也许--map-column-hive
这是不够的。同样,根据指向sqoop-1493的帖子,
--map-column-java
不支持java类型java.math.BigDecimal
至少在sqoopv1.4.7之前(现在还不清楚这个特定的选项是否支持它,以及它是否被预期为BigDecimal
或者java.math.BigDecimal
)实际上,由于sqoop1.4.7并非在所有发行版中都可用,而且由于您的问题没有得到很好的诊断,所以它可能不可行。
因此,我建议您在读取时通过将rogue oracle列转换为字符串来隐藏问题。
请参阅有关“sqoop-import”>“自由形式查询导入”的文档。。。
而不是使用
--table
,--columns
以及--where
参数,您可以使用--query
参数(…)您的查询必须包含标记$conditions(…),例如:$ sqoop import --query 'SELECT a.*, b.* FROM a JOIN b ON a.id=b.id WHERE $CONDITIONS' ...
就你而言,SELECT x, y, TO_CHAR(z) AS z FROM wtf
加上\u char中的适当格式,这样您就不会因为舍入而丢失任何信息。jvlzgdj92#
好的,我的第一个答案假设您的oracle数据是好的,而您的sqoop作业需要特定的配置来处理数值。
但现在我怀疑你的甲骨文数据里有狗屎,特别是
NaN
值,作为计算错误的结果。请参阅以下文章:oracle何时/为什么向数据库表中的行添加nan
而甲骨文甚至有明显的“非数字”类别来表示“无限”,使事情更加复杂。
但在 java 方面,
BigDecimal
不支持NaN
--从文档中,在所有转换方法中。。。抛出:
NumberFormatException
-如果值为无穷大或nan。请注意,jdbc驱动程序会屏蔽该异常并显示
NumericOverflow
相反,为了使调试更加复杂。。。所以你的问题看起来是这样的:solr numeric overflow(来自oracle)
--但不幸的是solr允许跳过错误,而sqoop则不允许;所以你不能用同样的伎俩。
最后,你将不得不“掩盖”这些
NaN
具有oracle函数的值NaNVL
,使用sqoop中的自由形式查询: