将分层的Oracle查询转换为DB2查询

时间:2019-03-21 22:14:55

标签: oracle sas db2

我主要使用SAS和Oracle,但对DB2还是一个新手。我面临着需要层次化查询来将Clob分成可以拉入sas的块的问题。 SAS的字符变量限制为32K,所以我不能正常地提取数据集。

我发现了一个古老的stackoverflow问题,它涉及将Clob放入sas数据集中的最佳方法,但是它是用Oracle编写的。 Import blob through SAS from ORACLE DB

由于我是DB2的新手,因此这种连接的语法似乎非常不同,所以我希望找到一个可以帮助转换它并解释语法的人。我发现Oracle语法更容易理解。我不确定在DB2中是否使用像这样的https://www.ibm.com/support/knowledgecenter/en/SSEPEK_10.0.0/apsg/src/tpc/db2z_xmprecursivecte.html的CTE递归还是使用像这样的https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_71/sqlp/rbafyrecursivequeries.htm的分层查询

这是Oracle查询。

SELECT    
      id  
    , level as chunk_id
    , regexp_substr(clob_value, '.{1,32767}', 1, level, 'n') as clob_chunk
FROM (
    SELECT id, clob_value
    FROM schema.table
    WHERE id = 1
)
CONNECT BY LEVEL <= regexp_count(clob_value, '.{1,32767}',1,'n')
order by id, chunk_id;

该表有两个字段,分别是id和clob_value,看起来像这样。

ID    CLOB_VALUE
1     really large clob
2     medium clob
3     another large clob

以为我想要这个结果。我只会一次在id =我正在处理的那一行上执行这一行。

ID  CHUNK_ID   CLOB
1   1       clob_chunk1of3
1   2       clob_chunk2of3
1   3       clob_chunk3of3

感谢您花费任何时间阅读和帮助。

2 个答案:

答案 0 :(得分:1)

这是一个几乎不需要更改即可在DB2中工作的解决方案(但是请注意,我一点也不了解DB2;我只是使用SQL标准中的Oracle功能,因此应该以相同的方式实现它们-或几乎如此-在DB2中)。

下面,我用您的示例数据创建一个表格;然后说明如何将其分块为最多8个字符的子字符串。尽管字符串很短,但我将列定义为CLOB,并且正在使用CLOB工具。这应该适用于更大的CLOB。

如果需要,可以将块大小和id都设置为绑定参数。在下面的演示中,我对块大小进行了硬编码,并在表中显示了所有ID的结果。如果CLOB为NULL,我会返回一个块(当然是NULL)。

请注意,在查询中触摸CLOB非常昂贵;因此,大多数工作无需触摸CLOB即可完成。我只会尽可能少地处理它们。

预备工作

drop table tbl purge;    -- If needed

create table tbl (id number, clob_value clob);

insert into tbl (id, clob_value)
  select 1, 'really large clob'  from dual union all
  select 2, 'medium clob'        from dual union all
  select 3, 'another large clob' from dual union all
  select 4, null                 from dual             -- added to check handling
;

commit;

查询

with
  prep(id, len) as (
    select id, dbms_lob.getlength(clob_value)
    from   tbl
  )
,  rec(id, len, ord, pos) as (
    select  id, len, 1, 1
      from  prep
    union all
    select  id, len, ord + 1, pos + 8
      from  rec
      where len >= pos + 8
  )
select   id, ord, dbms_lob.substr(clob_value, 8, pos)
from     tbl inner join rec using (id)
order by id, ord
;

  ID  ORD CHUNK   
---- ---- --------
   1    1 really l
   1    2 arge clo
   1    3 b       
   2    1 medium c
   2    2 lob     
   3    1 another 
   3    2 large cl
   3    3 ob      
   4    1        

答案 1 :(得分:0)

另一种选择是启用Oracle compatibility in Db2并只发出hierarchical query

GitHub repository has background information on SQL recursion in DB2,包括Oracle样式的语法和一个side by side example(两者均针对Db2示例数据库):

 User.findById(id)
    .then(function(user) {
      if (!user) {
        return "here you return an error";
      }

      return "you return OK with payload from database";
    })
    .catch(next);