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

如何在Oracle Apex中检索递归信息?,oracle,oracle-apex,Oracle,Oracle Apex,在我的Apex应用程序中,有机会设置用于创建图表的过滤器。如果用户愿意,可以选择多个系统。系统将作为复选框项创建。复选框项的来源基于一个值列表,其中包含一个SQL查询,用于从我的数据库表中检索所有系统。以下是我的数据库表的结构: CREATE TABLE system_table ( system_id NUMBER(16) NOT NULL, system_name VARCHAR2(100 CHAR) NOT NULL, sys

在我的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_ID的隐藏项。在提交页面之前,我定义了一个动态操作,该操作将拾取所选System_名称的ID。提交页面后,将创建图表,并检查where子句中的条件。看起来是这样的:

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))
到目前为止,查询仍在运行,但只选择所选系统名称,而不选择引用所选系统的系统。我希望我能解释这个问题,你也能理解。你们有谁知道我做错了什么吗

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

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”。此外,每个“Fahrt”包含几个触发器。最后四个条件是所提到的检索已设置的filterinformation的条件,并且仅统计满足筛选条件的触发器

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

此分层查询从选定的系统名称开始,并沿分层结构向上移动到其父母、祖父母等的顶部。生成的系统ID集然后用于过滤主表

如果需要它来选择所选系统的任何子系统,请切换
connectby
子句,例如

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
)

顺便说一句,您应该能够摆脱对系统名称的依赖,让值列表返回
system\u id
,而不需要DA来设置隐藏项。是的,我知道您完全正确,但我不知道如何做到这一点。如果我使用系统id作为返回值,过滤器将不再工作。它仅在我使用系统名称时有效。这是值列表查询的样子:
选择distinct(SYSTEM\u TABLE.SYSTEM\u NAME)作为display\u value,SYSTEM\u TABLE.SYSTEM\u NAME作为return\u value from SYSTEM\u TABLE order by SYSTEM\u TABLE.SYSTEM\u NAME
显然,如果更改列表项的返回值,您需要相应地更新查询以接受系统id值而不是系统名称。但这样做会更好,因为如果系统名恰好包含一个嵌入的冒号(
),它不会失败。您有很多(有效的)内部联接和谓词,它们可能会过滤掉您期望的结果。获取查询,注释掉所有不相关的位,然后测试它。如果出现预期的结果,请一次一个地逐渐添加一位,直到它们再次消失-然后您将知道哪个谓词或联接正在删除预期的结果。除系统筛选器外,所有筛选器都工作正常。这就是我开始写这篇文章的原因。谢谢你的回答。我试了一下。到目前为止,它正在编译,我得到了一些结果,但不幸的是,它们还不正确。也许我应该添加以下信息:我的层次结构的最大级别是1,这意味着我只有父母和孩子。父系统未引用任何其他系统。start with和connect by语句在做什么?此外,我正在选择父系统,因此我需要了解父系统的子系统。这可能就是为什么查询到目前为止不起作用的原因,因为您的解决方案目前正在以相反的方式进行查询,不是吗?没错,我的分层查询从子查询开始,然后以其方式运行到父查询。我会相应地更新答案。另外,如果你只对父母和孩子感兴趣,这意味着这不是一个真正有趣的层次结构,所以你不需要层次结构查询。谢谢!我尝试了你发布的最后一个查询,但在我看来仍然没有得到正确的结果。不幸的是,我不知道我在查询中的错误发生在哪里。在我看来,你提出的问题绝对有道理!如果我的父项在属性“system_table_uebergeordnet_id”中包含NULL,查询会有问题吗?因为现在就是这样,尽管所有其他子项都包含正确的值。在我看来,父对象在该属性中包含值也没有任何意义。所以我认为这应该是正确的..我希望父ID列的父ID应该为NULL。我不知道你在期待什么。是的,我也在期待。对于查询来说应该不是问题。
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
)