用于填充实体化视图的存储过程

时间:2018-08-16 14:25:26

标签: oracle

如何创建存储过程。 我们有一个父视图,其中的数据位于以下任一列中,

  • Link-ABCD * Link-Child01 * Link-Child02
  • Link-DEFG * Link-Child03 * Link-Child04
  • Link-XYZ * Link-Child05 * Link-Child04

我们要在具有以下结构的父视图之上创建一个物化视图,

ID_COLUMN | ELEMENT_COLUMN        | PARENT_ID_COLUMN
  1       |        Link-ABCD      |     0
  2       |        Link-Child01   |     1
  3       |        Link-Child02   |     2
  4       |        Link-DEFG      |     0
  5       |        Link-Child03   |     4
  6       |        Link-Child04   |     5
  7       |        Link-XYZ       |     0
  8       |        Link-Child05   |     7
  9       |        Link-Child04   |     8
   -
  • ID_Column =自动生成
  • ELEMENT_COLUMN =需要使用定界符“ *”分割父视图中存在的数据,并且仅在元素不存在之前或元素已经存在的情况下插入每个元素,然后我们需要检查现有元素的父ID元素,并且父代ID与当前父代的ID_COLUMN不同。例如,我们不得不再次插入 Link-Child04 ,因为上一种情况下父级是不同的。
  • PARENT_ID_COLUMN =值将与父元素的ID_COLUMN相同。例如,Link-Child01是Link-ABCD的子代,其ID为1,因此Link-Child01的parent_id必须为1,依此类推。 没有任何父元素的元素的parent_id将为0。例如,Link-ABCD,Link-DEFG和Link-XYZ的父ID为0。

2 个答案:

答案 0 :(得分:1)

您可以使用递归CTE(只要您使用的是Oracle 11gR2或更高版本)和排名函数来生成所需的结果。如果调用了parent_view中的列,例如str,则可以执行以下操作:

with rcte (str, root_rn, child_level, element) as (
  select str,
    row_number() over (order by str),
    1,
    regexp_substr(str, '(.*?)(\*|$)', 1, 1, NULL, 1)
  from parent_view
  union all
  select str,
    root_rn,
    child_level + 1,
    regexp_substr(str, '(.*?)(\*|$)', 1, child_level + 1, NULL, 1)
  from rcte
  where child_level <= regexp_count(str, '\*')
)
select rank() over (order by root_rn, child_level) as id,
  element,
  case when child_level = 1 then 0
       else rank() over (order by root_rn, child_level) - 1 end as parent_id
from rcte
order by root_rn, child_level;

其中包含示例字符串的

        ID ELEMENT               PARENT_ID
---------- -------------------- ----------
         1 Link-ABCD                     0
         2 Link-Child01                  1
         3 Link-Child02                  2
         4 Link-DEFG                     0
         5 Link-Child03                  4
         6 Link-Child04                  5
         7 Link-XYZ                      0
         8 Link-Child05                  7
         9 Link-Child04                  8

但是目前还不清楚您真正想要做什么。您可以从该查询创建普通视图或实例化视图,但是ID将随着在父视图(或更确切地说,在其基表中)添加,删除或修改行而改变。 (基于视图的视图可能会引入性能问题。)

您还可以使用相同的查询从过程中维护普通表;但这似乎是在重复物化视图为您提供的功能。


您可能还想查看父视图的查询,以查看这些字符串来自何处-只是一个猜测,但是它可能是通过汇总可以直接查看的基表中的值来生成它们的。

答案 1 :(得分:0)

如何提取3个字段的示例:

select a.link_info,
       substr(a.link_info,
              1,
              instr(a.link_info,'*',1,1)-1       /* Until 1st asterisk*/
              )                      as element1,
       substr(a.link_info,
              instr(a.link_info,'*',1,1)+1,     /* between 1st and 2nd asterisk*/
              instr(a.link_info,'*',1,2)-instr(a.link_info,'*',1,1)-1
              )                      as element2,
       substr(a.link_info,
              instr(a.link_info,'*',1,2)+1     /* after the 2nd asterisk */
              )                      as element3
from (select 'Link-ABCD*Link-Child01*Link-Child02' as link_info
      from dual
      union all
      select 'Link-DEFG*Link-Child03*Link-Child04' as link_info
      from dual
      union all
      select 'Link-XYZ*Link-Child05*Link-Child04' as link_info
      from dual
      ) a;
相关问题