如何在Oracle Apex中检索递归信息?

时间:2018-11-06 07:22:09

标签: oracle oracle-apex

在我的Apex应用程序中,有机会设置用于创建图表的过滤器。用户可以根据需要选择多个系统。系统被创建为复选框项目。复选框项的来源基于值列表,该值列表包含一个SQL查询以从数据库表中检索所有系统。这是我的数据库表的结构:

CREATE TABLE system_table (
system_id                  NUMBER(16) NOT NULL,
system_name                VARCHAR2(100 CHAR) NOT NULL,
system_table_uebergeordnet_ID NUMBER(16),
CONSTRAINT system_name_unique UNIQUE(system_name),
CONSTRAINT system_table_pk PRIMARY KEY ( system_id ),
CONSTRAINT system_table_uber_id_fk FOREIGN KEY ( system_table_uebergeordnet_ID )
    REFERENCES system_table ( system_id )   );

您可以在代码中看到,最后一个属性是递归关系。我现在想要的是以下内容:如果用户选择了system_name并提交了页面,则应该选择系统名称以及引用所选系统的所有其他系统。因此,我创建了一个名为System_ID的隐藏项。在提交页面之前,我已经定义了一个动态操作,该操作将拾取所选system_name的ID。提交页面后,将创建我的图表,并且正在检查子句中的条件。看起来像这样:

where ((instr(':' || upper(:P26_SYSTEMS) || ':', upper(SYSTEM_TABLE.SYSTEM_NAME)) > 0) or (instr(':' || upper(:P26_SYSTEMS_ALL) || ':', upper(SYSTEM_TABLE.SYSTEM_NAME)) > 0) or (SYSTEM_TABLE.SYSTEM_TABLE_UEBERGEORDNET_ID = :P26_SYSTEM_ID))

该查询到目前为止一直有效,但仅选择所选的system_name,而不选择引用所选系统的系统。我希望我能够解释这个问题,并且您可以理解。你们当中有人知道我在做什么错吗?

以下代码显示了我的查询:

select COUNT(TRIGGER_TABLE.DATUM_UHRZEIT) as Anzahl_Trigger,
       TEST.NUMMER as NUMMER
from BRIDGE_SYSTEM_TRIGGER, SYSTEM_TABLE, TRIGGER_TABLE, FAHRT, TEST, MITARBEITER
where BRIDGE_SYSTEM_TRIGGER.SYSTEM_TABLE_SYSTEM_ID = SYSTEM_TABLE.SYSTEM_ID
      and BRIDGE_SYSTEM_TRIGGER.TRIGGER_TABLE_TRIGGER_ID = TRIGGER_TABLE.TRIGGER_ID
      and TRIGGER_TABLE.FAHRT_FAHRT_ID = FAHRT.FAHRT_ID
      and MITARBEITER.NUMMER = FAHRT.MITARBEITER_NUMMER
      and FAHRT.TEST_ID= TEST_ID
      and TRIGGER_TABLE.PRIORITAET = 1
      and ((instr(':' || upper(:P26_TEST) || ':', upper(TEST.TEST_ID)) > 0) or (instr(':' || upper(:P26_TEST_ALL) || ':', upper(TEST.TEST_ID)) > 0))
      and ((instr(':' || upper(:P26_SYSTEMS) || ':',':' || upper(system_table.system_name) ||':') > 0)  or (instr(':' || upper(:P26_SYSTEMS_ALL) || ':', upper(SYSTEM_TABLE.SYSTEM_NAME)) > 0) or exists (select child.system_id from system_table child where  instr(':' || upper(:P26_SYSTEMS) ||':',':'|| upper(child.system_name) ||':') > 0 and child.system_table_uebergeordnet_id = system_table.system_id))
      and ((instr(':' || upper(:P26_COUNTRIES) || ':', upper(FAHRT.LAND)) > 0) or (instr(':' || upper(:P26_COUNTRIES_ALL) || ':', upper(FAHRT.LAND)) > 0))
      and ((instr(':' || upper(:P26_FAHRER) || ':', upper(MITARBEITER.QNUMMER)) > 0) or (instr(':' || upper(:P26_FAHRER_ALL) || ':', upper(MITARBEITER.QNUMMER)) > 0))
GROUP BY TEST.NUMMMER
ORDER BY TEST.NUMMER;

该查询对Testnumbers排序的每个优先级的触发器数量进行计数。 此处所指的触发器与sql触发器无关!因此,请不要对这个术语感到困惑。 “ Fahrt”属于一个“ Test”,一个“ Test”可以包含多个“ Fahrten”。此外,每个“法赫特”都包含多个触发器。最后四个条件是提及的条件,这些条件用于检索已设置的过滤器信息,并且仅对满足过滤器条件的那些触发器进行计数。

1 个答案:

答案 0 :(得分:2)

可以使用分层查询来查询分层数据结构。在Oracle中,您可以使用类似以下内容(注意:未经测试):

select ...
from system_table
where instr(':'||upper(:P26_SYSTEMS)||':'
           ,':'||upper(system_table.system_name)||':') > 0
or system_table.system_id in (
  select parent.system_id
  from   system_table parent
  start with instr(':'||upper(:P26_SYSTEMS)||':'
                  ,':'||upper(parent.system_name)||':') > 0
  connect by prior parent.system_table_uebergeordnet_id = parent.system_id
)

此层次结构查询从选定的系统名称开始,然后将层次结构向上移至其父母,祖父母等。然后将得到的一组系统ID用来过滤主表。

如果需要它来选择选定系统的任何子级,请切换connect by子句,例如

select ...
from system_table
where instr(':'||upper(:P26_SYSTEMS)||':'
           ,':'||upper(system_table.system_name)||':') > 0
or system_table.system_id in (
  select parent.system_id
  from   system_table parent
  start with instr(':'||upper(:P26_SYSTEMS)||':'
                  ,':'||upper(parent.system_name)||':') > 0
  connect by prior parent.system_id = parent.system_table_uebergeordnet_id
)

另一方面,如果它不是多级层次结构,则可以简化查询,例如

select ...
from system_table
where instr(':'||upper(:P26_SYSTEMS)||':'
           ,':'||upper(system_table.system_name)||':') > 0
or exists (
  select child.system_id
  from   system_table child
  where  instr(':'||upper(:P26_SYSTEMS)||':'
              ,':'||upper(parent.system_name)||':') > 0
  and    child.system_table_uebergeordnet_id = system_table.system_id
)