Oracle:为什么SQL代码可以在视图中工作,而不能在物化视图中工作?

vbopmzt1  于 2022-12-18  发布在  Oracle
关注(0)|答案(1)|浏览(149)

我需要将视图中的一些SQL代码更改为示例化视图。
但当我复制并使用它时,我得到一个错误:
ORA-32480:只能为递归WITH子句元素指定SEARCH和CYCLE子句
我不明白为什么在视图中有效的东西在主视图中也有效。
有谁知道我该如何消除这个错误吗?这个问题发生在调用另一个查询的连接中。我也尝试了递归,但不知何故,它不起作用。

with
  z1  (einheit_id, ancestor_einheit_id, ueb_einheit_id, is_root, kiste_id, nodepath)  as (
       select     e.id as einheit_id, e.id as ancestor_einheit_id, e.ueb_einheit_id, 0 as is_root,  e.kiste_id, cast(to_char(e.id) as varchar2(1024)) as nodepath
       from       r_be_einheit e
       where      e.kiste_id = -2
       union all
       select     z1.einheit_id, coalesce(e1.id,e2.id) as ancestor_einheit_id, coalesce(e1.ueb_einheit_id, e2.ueb_einheit_id) as ueb_einheit_id,
                  0 as is_root, coalesce(e1.kiste_id,e2.kiste_id) as kiste_id,
                  z1.nodepath ||  '/' || cast(to_char(coalesce(e1.id,e2.id)) as varchar2(1024)) as nodepath                 
       from       z1
       left join  r_be_einheit e1 on e1.id = z1.ueb_einheit_id
       left join  r_be_einheit e2 on e2.merge_einheit_id = z1.ancestor_einheit_id
       where      z1.is_root = 0 and (e1.id is not null or e2.id is not null) and instr(z1.nodepath, '/' || to_char(coalesce(e1.id,e2.id))) = 0
       )  cycle nodepath set is_cycle to 1 default 0
    ,
    einheiten as (
    select      e.id as be_einheit_id,
                e.barcode,
                e.objektart_id
    from        r_be_einheit e
    left join   z1 on e.id = z1.einheit_id
  )
  ,
  og_zuo0 as (
    select e.barcode
    from  einheiten e
  )
  ,
  og_zuo1 as (
    select *
    from einheiten e
    join og_zuo0 on og_zuo0.barcode = e.barcode
  )
  select * from og_zuo1

我把代码写得很深了,错误还是出现了。我把代码写得很深了,错误还是出现了。这是最后一个连接。如果我删除og_zuo1,并在最后选择og_zuo0,那么错误就不会出现。但我不明白为什么。

fquxozlt

fquxozlt1#

您可以将代码重写为:

with z1  (einheit_id, ancestor_einheit_id, ueb_einheit_id, is_root, kiste_id, nodepath) as (
  select id,
         id,
         ueb_einheit_id,
         0,
         kiste_id,
         cast(to_char(id) as varchar2(1024))
  from   r_be_einheit
  where  kiste_id = -2
union all
  select z1.einheit_id,
         coalesce(e1.id,e2.id),
         coalesce(e1.ueb_einheit_id, e2.ueb_einheit_id),
         0,
         coalesce(e1.kiste_id,e2.kiste_id) as kiste_id,
         z1.nodepath ||  '/' || to_char(coalesce(e1.id,e2.id))
  from   z1
         left join  r_be_einheit e1
         on e1.id = z1.ueb_einheit_id
         left join  r_be_einheit e2
         on e2.merge_einheit_id = z1.ancestor_einheit_id
  where  z1.is_root = 0
  and    (e1.id is not null or e2.id is not null)
  and    instr(z1.nodepath, '/' || to_char(coalesce(e1.id,e2.id))) = 0
) cycle nodepath set is_cycle to 1 default 0,
einheiten as (
  select e.id as be_einheit_id,
         e.barcode,
         e.objektart_id
  from   r_be_einheit e
         left join z1
         on e.id = z1.einheit_id
)
select e.*,
       e0.barcode
from   einheiten e
       join einheiten e0
       on e0.barcode = e.barcode

尽管我不确定最终查询中自连接的值是什么;但它在那里是因为它复制了og_zuo1中的连接。

einheiten as (
  select e.id as be_einheit_id,
         e.barcode,
         COUNT(*) OVER (PARTITION BY e.barcode) AS num_rows,
         e.objektart_id
  from   r_be_einheit e
         left join z1
         on e.id = z1.einheit_id
)
select e.*,
       e.barcode
from   einheiten e
       CROSS APPLY (
         SELECT 1 FROM DUAL CONNECT BY LEVEL <= e.num_rows
       )

fiddle

相关问题