Oracle APEX技术咨询:共享组件使用排查及未使用组件列表生成
嘿,这些问题都是Oracle APEX开发中经常碰到的场景,我来给你分享下实用的解决方案:
1. 如何查询应用内哪些页面使用了特定共享组件?
有两种常用方式,看你更偏向哪种:
- 可视化操作(不用写SQL):进入应用的「共享组件」,找到你要查询的目标组件(比如LOV、动态动作、项集等),点击组件名称进入详情页,然后点击页面右上角的查找引用按钮。APEX会自动生成一个报表,清晰列出所有引用这个组件的页面、项、区域、动态动作等位置,非常直观。
- SQL查询(灵活定制):如果需要更个性化的结果,比如过滤特定页面或者导出数据,可以用APEX的内置视图写查询。比如查询某个LOV的所有引用位置:
SELECT p.page_id, p.page_name, i.item_name, '页面项' AS reference_type FROM APEX_APPLICATION_PAGE_ITEMS i JOIN APEX_APPLICATION_PAGES p ON i.application_id = p.application_id AND i.page_id = p.page_id WHERE i.application_id = :APP_ID AND i.lov_name = 'YOUR_TARGET_LOV_NAME' -- 替换成你的LOV名称 UNION ALL SELECT p.page_id, p.page_name, r.region_name, '区域' AS reference_type FROM APEX_APPLICATION_PAGE_REGIONS r JOIN APEX_APPLICATION_PAGES p ON r.application_id = p.application_id AND r.page_id = p.page_id WHERE r.application_id = :APP_ID AND r.lov_name = 'YOUR_TARGET_LOV_NAME';
不同类型的共享组件对应不同的视图,比如动态动作用APEX_APPLICATION_DYNAMIC_ACTIONS,项集用APEX_APPLICATION_ITEM_SETS,按需替换就行。
2. 是否可以生成应用未使用的共享组件列表?
当然可以!通过对比共享组件表和所有引用位置的视图,就能找出没有被引用的组件。这里分享一个我常用的SQL片段,用来找出未使用的LOV:
SELECT lov_name, lov_id, created_by, last_updated_on FROM APEX_APPLICATION_LOVS WHERE application_id = :APP_ID -- 排除被页面项、区域、动态动作引用的LOV AND lov_id NOT IN ( SELECT DISTINCT lov_id FROM APEX_APPLICATION_PAGE_ITEMS WHERE application_id = :APP_ID UNION SELECT DISTINCT lov_id FROM APEX_APPLICATION_PAGE_REGIONS WHERE application_id = :APP_ID UNION SELECT DISTINCT lov_id FROM APEX_APPLICATION_DYNAMIC_ACTIONS WHERE application_id = :APP_ID ) -- 排除APEX系统自带的组件(名称通常以APEX开头) AND lov_name NOT LIKE 'APEX%';
如果要找其他类型的未使用组件,比如动态动作,只需要把APEX_APPLICATION_LOVS换成APEX_APPLICATION_DYNAMIC_ACTIONS,然后调整引用查询的逻辑即可。注意:如果有些组件被其他共享组件引用(比如LOV被另一个LOV嵌套引用),上面的SQL可能会误判,这种情况可以额外加入共享组件之间的引用查询,不过日常开发里上面的SQL已经能覆盖大部分场景了。
3. 如何创建特定共享组件所有使用位置的报表?
可以直接在APEX里创建一个交互式报表,步骤如下:
- 进入应用构建器,点击「创建页面」,选择「报表」->「交互式报表」,设置页面名称(比如“共享组件引用查询”)。
- 在「SQL查询」区域,输入通用的引用查询SQL,比如下面这个支持查询LOV引用的(可以扩展到其他组件):
SELECT reference_type, page_id, page_name, object_name, component_name FROM ( SELECT '页面项' AS reference_type, p.page_id, p.page_name, i.item_name AS object_name, i.lov_name AS component_name FROM APEX_APPLICATION_PAGE_ITEMS i JOIN APEX_APPLICATION_PAGES p ON i.application_id = p.application_id AND i.page_id = p.page_id WHERE i.application_id = :APP_ID UNION ALL SELECT '区域' AS reference_type, p.page_id, p.page_name, r.region_name AS object_name, r.lov_name AS component_name FROM APEX_APPLICATION_PAGE_REGIONS r JOIN APEX_APPLICATION_PAGES p ON r.application_id = p.application_id AND r.page_id = p.page_id WHERE r.application_id = :APP_ID UNION ALL SELECT '动态动作' AS reference_type, p.page_id, p.page_name, da.action_name AS object_name, da.lov_name AS component_name FROM APEX_APPLICATION_DYNAMIC_ACTIONS da JOIN APEX_APPLICATION_PAGES p ON da.application_id = p.application_id AND da.page_id = p.page_id WHERE da.application_id = :APP_ID ) WHERE component_name = :P1_TARGET_COMPONENT -- 绑定页面项作为查询参数 ORDER BY page_id, reference_type;
- 创建一个页面项(比如
P1_TARGET_COMPONENT),类型设为「选择列表」,数据源选择当前应用的所有LOV(或者你要查询的组件类型),让用户可以选择要查询的组件。 - 配置报表的筛选、排序和导出功能,这样用户就能随时查询任意组件的所有引用位置了。
如果需要支持多种组件类型的查询,可以再增加一个组件类型的选择项,用CASE或者动态SQL来调整查询逻辑,不过对大多数场景来说,单一组件类型的报表已经足够实用。
内容的提问来源于stack exchange,提问作者Coding Duchess
相关产品推荐
相关产品推荐

