我用sqoop从oracle导入数据到hdfs时,总是报 表或视图不存在错误,求解答...

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我用sqoop从oracle导入数据到hdfs时,总是报 表或视图不存在错误,求解答...相关的知识,希望对你有一定的参考价值。

表在oracle,XE数据库实例中已经建好,并且命令中的名字也没有错
具体的信息
[root@hadoop03 bin]# ./sqoop import --connect jdbc:oracle:thin:@192.168.8.100:1521:xe --username hadoop --password hadoop --table person

15/04/29 01:41:07 INFO manager.SqlManager: Using default fetchSize of 1000
15/04/29 01:41:07 INFO tool.CodeGenTool: Beginning code generation
15/04/29 01:41:07 INFO manager.OracleManager: Time zone has been set to GMT
15/04/29 01:41:07 INFO manager.SqlManager: Executing SQL statement: SELECT t.* FROM person t WHERE 1=0
15/04/29 01:41:07 ERROR manager.SqlManager: Error executing statement: java.sql.SQLException: ORA-00942: 表或视图不存在

java.sql.SQLException: ORA-00942: 表或视图不存在

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:573)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1891)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteDescribe(TTC7Protocol.java:830)
at oracle.jdbc.driver.OracleStatement.doExecuteQuery(OracleStatement.java:2391)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2672)

15/04/29 01:41:07 ERROR tool.ImportTool: Encountered IOException running import job:

参考技术A 通过配置本地数据库的tns配置文件实现:
去oracle安装目录下oracle\product\10.2.0\db_2\NETWORK\ADMIN\ 找到tnsnames.ora,用记事本打开,里边有远程数据库的tns连接配置串如下
ORCL23 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.3.23)(PORT = 1521))
)
(CONNECT_DATA =
(SID = ORCL)
)
)
添加好ip、端口和目标数据库的实例名(SID),然后确保tns名称(ORCL23)在整个文档中唯一,保存后打开数据库连接工具,输入远程数据库上的用户名密码,选择数据库对象为你配置的连接名就可以了
参考技术B 回答的和提出的问题不在一个频道。
我最近也遇到了这个问题。
list-tables 看数据表是存在的,imoprt时候总是报错提示 表示图不存在。
后来把表名改成大写字母,OK问题解决。我也是醉了。。。
--table PERSON

利用SQOOP将数据从数据库导入到HDFS(并行导入,增量导入)

基本使用

如下面这个shell脚本:

#Oracle的连接字符串,其中包含了Oracle的地址,SID,和端口号
CONNECTURL=jdbc:oracle:thin:@20.135.60.21:1521:DWRAC2
#使用的用户名
ORACLENAME=kkaa
#使用的密码
ORACLEPASSWORD=kkaa123
#需要从Oracle中导入的表名
oralceTableName=tt
#需要从Oracle中导入的表中的字段名
columns=AREA_ID,TEAM_NAME
#将Oracle中的数据导入到HDFS后的存放路径
hdfsPath=apps/as/hive/$oralceTableName

#执行导入逻辑。将Oracle中的数据导入到HDFS中
sqoop import --append --connect $CONNECTURL --username $ORACLENAME --password $ORACLEPASSWORD --target-dir $hdfsPath  --num-mappers 1 --table $oralceTableName --columns $columns --fields-terminated-by ‘\001‘

执行这个脚本之后,导入程序就完成了。

接下来,用户可以自己创建外部表,将外部表的路径和HDFS中存放Oracle数据的路径对应上即可。

注意:这个程序导入到HDFS中的数据是文本格式,所以在创建Hive外部表的时候,不需要指定文件的格式为RCFile,而使用默认的TextFile即可。数据间的分隔符为‘\001‘。如果多次导入同一个表中的数据,数据以append的形式插入到HDFS目录中。

并行导入

假设有这样这个sqoop命令,需要将Oracle中的数据导入到HDFS中:

sqoop import --append --connect $CONNECTURL --username $ORACLENAME --password $ORACLEPASSWORD --target-dir $hdfsPath  --m 1 --table $oralceTableName --columns $columns --fields-terminated-by ‘\001‘  --where "data_desc=‘2011-02-26‘"

请注意,在这个命令中,有一个参数“-m”,代表的含义是使用多少个并行,这个参数的值是1,说明没有开启并行功能。

现在,我们可以将“-m”参数的值调大,使用并行导入的功能,如下面这个命令:

sqoop import --append --connect $CONNECTURL --username $ORACLENAME --password $ORACLEPASSWORD --target-dir $hdfsPath  --m 4 --table $oralceTableName --columns $columns --fields-terminated-by ‘\001‘  --where "data_desc=‘2011-02-26‘"

一般来说,Sqoop就会开启4个进程,同时进行数据的导入操作。

但是,如果从Oracle中导入的表没有主键,那么会出现如下的错误提示:

ERROR tool.ImportTool: Error during import: No primary key could be found for table creater_user.popt_cas_redirect_his. Please specify one with --split-by or perform a sequential import with ‘-m 1‘.

在这种情况下,为了更好的使用Sqoop的并行导入功能,我们就需要从原理上理解Sqoop并行导入的实现机制。

如果需要并行导入的Oracle表的主键是id,并行的数量是4,那么Sqoop首先会执行如下一个查询:

select max(id) as max, select min(id) as min from table [where 如果指定了where子句];

通过这个查询,获取到需要拆分字段(id)的最大值和最小值,假设分别是1和1000。

然后,Sqoop会根据需要并行导入的数量,进行拆分查询,比如上面的这个例子,并行导入将拆分为如下4条SQL同时执行:

select * from table where 0 <= id < 250;

select * from table where 250 <= id < 500;

select * from table where 500 <= id < 750;

select * from table where 750 <= id < 1000;

注意,这个拆分的字段需要是整数。

从上面的例子可以看出,如果需要导入的表没有主键,我们应该如何手动选取一个合适的拆分字段,以及选择合适的并行数。

再举一个实际的例子来说明:

我们要从Oracle中导入creater_user.popt_cas_redirect_his。

这个表没有主键,所以我们需要手动选取一个合适的拆分字段。

首先看看这个表都有哪些字段:

然后,我假设ds_name字段是一个可以选取的拆分字段,然后执行下面的sql去验证我的想法:

select min(ds_name), max(ds_name) from creater_user.popt_cas_redirect_his where data_desc=‘2011-02-26‘

发现结果不理想,min和max的值都是相等的。所以这个字段不合适作为拆分字段。

再测试一下另一个字段:CLIENTIP
select min(CLIENTIP), max(CLIENTIP) from creater_user.popt_cas_redirect_his where data_desc=‘2011-02-26‘

这个结果还是不错的。所以我们使用CLIENTIP字段作为拆分字段。

所以,我们使用如下命令并行导入:

sqoop import --append --connect $CONNECTURL --username $ORACLENAME --password $ORACLEPASSWORD --target-dir $hdfsPath  --m 12 --split-by CLIENTIP --table $oralceTableName --columns $columns --fields-terminated-by ‘\001‘  --where "data_desc=‘2011-02-26‘"

这次执行这个命令,可以看到,消耗的时间为:20mins, 35sec,导入了33,222,896条数据。

另外,如果觉得这种拆分不能很好满足我们的需求,可以同时执行多个Sqoop命令,然后在where的参数后面指定拆分的规则。如:

sqoop import --append --connect $CONNECTURL --username $ORACLENAME --password $ORACLEPASSWORD --target-dir $hdfsPath  --m 1 --table $oralceTableName --columns $columns --fields-terminated-by ‘\001‘  --where "data_desc=‘2011-02-26‘ logtime<10:00:00"

sqoop import --append --connect $CONNECTURL --username $ORACLENAME --password $ORACLEPASSWORD --target-dir $hdfsPath  --m 1 --table $oralceTableName --columns $columns --fields-terminated-by ‘\001‘  --where "data_desc=‘2011-02-26‘ logtime>=10:00:00"

从而达到并行导入的目的。

增量导入

 

sqoop支持两种增量导入模式,
 一种是 append,即通过指定一个递增的列,比如:
--incremental append  --check-column num_iid --last-value 0

varchar类型的check字段也可以通过这种方式增量导入(ID为varchar类型的递增数字):

--incremental append  --check-column ID --last-value 8
另种是可以根据时间戳,比如:
--incremental lastmodified --check-column created --last-value ‘2012-02-01 11:0:00‘ 
就是只导入created 比‘2012-02-01 11:0:00‘更大的数据。

以上是关于我用sqoop从oracle导入数据到hdfs时,总是报 表或视图不存在错误,求解答...的主要内容,如果未能解决你的问题,请参考以下文章

利用SQOOP将数据从数据库导入到HDFS(并行导入,增量导入)

sqoop连接MySQL导入hdfs报错

sqoop 从oracle抽数据是 sql怎么写

如何从Oracle到hive

Sqoop从本地MySQL导入到Hive为啥要求Sqoop一定要在HDFS中

安装 sqoop