使用 sqoop 的两个 (PL)/SQL 查询

Posted

技术标签:

【中文标题】使用 sqoop 的两个 (PL)/SQL 查询【英文标题】:Two (PL)/SQL queries using sqoop 【发布时间】:2017-05-19 14:00:40 【问题描述】:

我正在尝试使用 sqoop 1.4.6 将数据从 Oracle 数据库导入 HDFS。使用--table table_name--query SELECT <...> 语句对HDFS 或hive 表进行简单导入没有问题。

但是,我的问题是:有没有办法通过先执行某个 PL/SQL 过程来导入表?

例如,假设存在一个过程set_date(date IN DATE),该过程在 Oracle 数据库中指定,用于设置数据的报告日期。使用常用的 JDBC 工具(即,ROracle 包,如果从 R 工作),同一连接需要两个查询来提取数据:

1) BEGIN set_date(#some_date#); END;

2)SELECT * FROM table_name;

使用sqoop 是否可以达到相同的结果?我尝试通过以下方法将两个查询混合为一个:

sqoop import --connect jdbc:oracle:thin@LINK:PORT:SID \
--username user -P \
--target-dir /some/directory \
--query "BEGIN set_date(#some_date#); END; SELECT * FROM table_name"

但显然整个查询被假定为 PL/SQL 格式,因此查询的 2) 部分没有按预期制定。另外,我已经尝试eval'ing 仅查询的set_date 部分,这似乎工作正常,所以唯一的问题是正确执行 2) SQL 查询。

是否可以使用相同的 sqoop 连接调用第二个查询? 是否可以使用 sqoop 将 1) 和 2) 语句混合为一个以获得相同的结果(现在一个简单的选择表就足够了)?

注意:我没有太多使用 SQL 和 PL/SQL 的经验,如果我没有足够清楚地指定某些部分,非常抱歉。

【问题讨论】:

我不知道 sqoop,但是如果您使用的是 Oracle 12.1,您可以尝试将这两个语句组合成一个匿名块并返回一个隐式结果集,类似于 ***.com/a/43451151/230471跨度> 【参考方案1】:

有点疯狂的猜测,因为我不知道 Sqoop,但是从 Oracle 12.1 开始,匿名 PL/SQL 块 cab 隐式返回结果集,所以如果 Sqoop 支持这一点,那么块可能是:

declare
    rc sys_refcursor;
begin
    set_date(#some_date#);

    open rc for select * from table_name;
    dbms_sql.return_result(rc);
end;

【讨论】:

谢谢,会看看,虽然我目前在 Oracle 11g 上。 运行后报错:PLS-00201: identifier 'DMBS_SQL.RETURN_RESULT' must be declared,可能是因为使用的Oracle版本?此外,尝试打开 :rc 并在之后打印它,但到目前为止没有运气。还有其他已知的解决方法吗? 隐式结果集是 12c 中的新功能。

以上是关于使用 sqoop 的两个 (PL)/SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

SQOOP -- 在 SQL Server 中使用 SCHEMA 查询

PL/SQL 不存在查询

使用 SQL 或 PL/SQL 对多个表中的列和表名进行动态查询

如何使用绑定变量使整个 PL/SQL 代码块动态化?

如何从选择查询向 PL/SQL 循环提供值

Sqoop 导入具有带 where 子句和并行处理的 SQL 查询