通过 SAS 从 ORACLE DB 导入 blob

Import blob through SAS from ORACLE DB

祝大家一天愉快。 我在上周的工作中遇到了一个大问题。 这是一笔交易:

我需要通过 SAS 从 ORACLE 数据库下载 exel 文件 (blob)。 我正在使用:

  1. 第一步我需要从 oracle 获取数据。我用的构造(blob文件将近100kb):

    proc sql;
    connect to oracle;
    create table SASTBL as 
    select * from connection to oracle (
    select dbms_lob.substr(myblobfield,1,32767) as blob_1,
    dbms_lob.substr(myblobfield,32768,32767) as blob_2,
    dbms_lob.substr(myblobfield,65535,32767) as blob_3,
    dbms_lob.substr(myblobfield,97302,32767) as blob_4
    
      from my_tbl;
    );
    quit;
    

结果是:

    blob_1 = 70020202020202...02
    blob_2 = 02020202020...02
    blob_3 = 02020202...02

我不明白为什么该字段由“02”(整个文件)组成

并且sas中任意变量的长度都是1024(而不是37767)$HEX2024格式。 如果我要:

dbms_lob.substr(my_blob_field,2000,900) 来自同一个对象,结果将更接近事实: 斑点 = "A234ABC4536AE7...."

问题是:1. 如何通过 SAS 从 blob 字段中正确获取二进制数据?我的错误是什么?

谢谢。

编辑 1:

我得到了信息,但最大字符串是 2000 kb。

PROC SQL 使用 SQL 与 SAS 数据集交互(创建表、查询表、聚合数据、外部连接等)。该过程主要遵循 ANSI 标准和一些 SAS 特定扩展。每个 RDMS 都扩展了 ANSI,包括 Oracle 及其 XML 处理,例如将内容保存在 blob 列中。 SAS 可能无法正确读取特定于 Oracle 的(非 ANSI)二进制大对象类型。通常 SAS 处理字符串、数字、日期时间和少数其他类型。

作为替代方案,考虑将来自 Oracle 的 XML 内容保存为 .xml 文件并使用 SAS 的 XML 引擎将内容读入 SAS 数据集:

** STORING XML CONTENT; 
libname tempdata xml 'C:\Path\To\XML\File.xml';

** APPEND CONTENT TO SAS DATASET;
data Work.XMLData;
   set tempdata.NodeName;        /* CHANGE TO REPEAT PARENT NODE OF XML. */
run;

在 CONNECT 语句(或 LIBNAME 语句)上使用 DBMAX_TEXT 选项以获得最多 32,767 个字符。默认值可能是 1024。

添加为另一个答案,因为我还不能发表评论...您遇到的问题是 dbms_lob.substr 的 return 实际上是一个 varchar,因此 SAS 将其限制为 2,000。为避免这种情况,您可以将其包装在 to_clob( ... ) AND 中,如前所述设置 DBMAX_TEXT 选项。

另一种选择如下...

下面的代码是使用大型 CLOB 检索单个记录的有效方法。它不是计算将 clob 拆分成多少个字段以产生非常宽的记录,而是将其拆分为多行。请参阅底部的预期输出。

免责声明:虽然有效,但可能效率不高,即可能无法很好地扩展到多行,因此普遍接受的方法是行流水线 PLSQL。话虽这么说,如果你不能做一个程序,下面的内容让我摆脱了困境...

PROC SQL;
connect to oracle (authdomain=YOUR_Auth path=devdb DBMAX_TEXT=32767 );
create table clob_chunks (compress=yes) as
select *
from connection to Oracle (
    SELECT    id
        , key   
        , level clob_order
        , regexp_substr(clob_value, '.{1,32767}', 1, level, 'n') clob_chunk
    FROM (
        SELECT id, key, clob_value
        FROM schema.table
        WHERE id = 123
    )
    CONNECT BY LEVEL <= regexp_count(clob_value, '.{1,32767}',1,'n')
)
order by id, key, clob_order;

disconnect from oracle;

QUIT;   

预期输出:

ID  KEY CHUNK   CLOB
1   1   1   short_clob
2   2   1   long clob chunk1of3
2   2   2   long clob chunk2of3
2   2   3   long clob chunk3of3
3   3   1   another_short_one

解释:

  1. DBMAX_TEXT 告诉 SAS 调整 clob 字段的默认值 1024。
  2. 正则表达式 .{1,32767} 告诉 Oracle 至少匹配一次但不超过 32767 次。这会拆分输入并捕获长度可能小于 32767 的最后一个块。
  3. regexp_substr 正在从 clob (param2) 的开头从 clob (param1) 中拉出一个块,跳到第“级别”出现 (param3) 并将 clob 视为一个大块字符串 (param4 'n').
  4. connect by 重新运行正则表达式来计算块数以停止级别递增超出 clob 的末尾。

参考文献: