使用Sqoop将S3中EMR输出的EmployeeID导入Oracle RAW(16)字段失败求助
解决Sqoop导出十六进制字符串到Oracle RAW(16)字段失败的问题
问题根源
Oracle的RAW(16)字段存储的是16字节的二进制数据,而你从EMR得到的F576334E17894499B6334E178974990B是32位的十六进制字符串(每两个字符对应一个字节),直接导出会因类型不匹配报错。
可行解决方案
方案1:在Sqoop命令中用Oracle的HEXTORAW函数转换
导出时通过字段映射参数指定类型,并对目标字段调用转换函数:
sqoop export \ --connect jdbc:oracle:thin:@//<oracle-host>:<port>/<service-name> \ --username <username> \ --password <password> \ --table EMPLOYEE \ --export-dir s3://<your-s3-path>/ \ --input-fields-terminated-by ',' \ --map-column-java EmployeeID=String \ --map-column-oracle EMPLOYEEID=RAW(16) \ --columns "HEXTORAW(EmployeeID), <其他字段>"
注意:需按表字段顺序列出所有字段,仅对EmployeeID应用HEXTORAW转换。
方案2:预处理EMR输出数据,转十六进制字符串为二进制
在EMR的Spark/Hive任务中直接完成转换,再输出到S3,让Sqoop导出时直接匹配RAW类型:
- Hive中用
unhex()函数:
SELECT unhex(EmployeeID) AS EmployeeID, <其他字段> FROM your_emr_table INSERT OVERWRITE DIRECTORY 's3://<your-s3-path>' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
- Spark中用
unhex函数(Scala示例):
import org.apache.spark.sql.functions.unhex df.withColumn("EmployeeID", unhex($"EmployeeID")) .write .option("delimiter", ",") .csv("s3://<your-s3-path>")
预处理后执行常规Sqoop导出命令即可。
方案3:自定义Sqoop类型转换器
若上述方案不适用,可编写自定义转换器将Java String类型转为Oracle RAW类型,打包成Jar后在Sqoop命令中用--jar-file参数加载。
常见报错排查
- 若出现
ORA-01460: unimplemented or unreasonable conversion requested,说明未正确完成字符串到RAW的转换,优先检查HEXTORAW函数的应用是否正确。 - 若出现
ORA-12899: value too large for column "EMPLOYEEID" (actual: 32, maximum: 16),说明直接将字符串作为RAW导入导致长度超限,必须用转换函数转成16字节二进制数据。
内容的提问来源于stack exchange,提问作者AccumuloUser
相关产品推荐
相关产品推荐

