简介《Oracle APEX深入浅出》配套文档面向希望快速掌握 Oracle APEX 的企业级 Web 应用开发者与数据库从业人员覆盖从入门认知到项目部署的完整知识链路。整包仅含1个 doc 文档约8.11MB以单份手册形式组织内容便于集中阅读和按章节检索。文档从 APEX 简介、环境搭建与账户权限管理讲起逐步展开页面布局美化、常用控件、Report 增删改、文件上传下载、CSS 与 JS 交互以及图表报表等深入开发要点并延伸到 Free Plugins、应用部署、调试技巧与常用 API。内容还涉及 EBS 中配置 APEX 页面调用等集成场景可帮助读者理解开发流程、积累排错思路并对照实际项目查阅。已有1592人学习适合作为 APEX 开发过程中的参考指南。1. 为什么一套页面都存在数据库里的开发工具值得你花一个下午装一遍做 ERP 二次开发的人多半被 Form 那套东西折腾过改一个字段要编译、要打补丁、要搬环境测试到生产的路径长得让人怀疑人生。第一次打开 Oracle APEX 的管理后台我的反应是这不就是一个网页版的 Form 个性化吗。这个判断八九不离十APEX 的页面不是磁盘上的文件而是数据库里的行加一堆 PL/SQL 包改布局等于改元数据提交即生效既没有编译步骤也没有部署包。也正因为这一点它的门槛和坑都集中在同一处——环境与元数据管理。这份《Oracle APEX 深入浅出》做的正是从装库、清旧版本、管账户到 Grid Layout 排版、Dynamic Action、Tabular Form 增删改、再到与 ERP 套件集成的完整链路讲的是 Oracle APEX 深入开发里那些配一下就好背后的原理。适合已经会写 SQL/PL/SQL、但不想在前后端框架上耗时间的后端同学也适合接手老系统、需要快速给业务开查询或录入界面的人。2. 环境搭建从 11g 自带 3.0 升到 4.2.5六个脚本按顺序跑2.1 先搞懂运行机制再决定用什么网关APEX 引擎完全驻留在数据库里由数据字典中的元数据表和大量 PL/SQL 对象组成。浏览器发来的 URL 请求被一个 HTTP 入口解析成 PL/SQL 调用数据库处理完再用sys.htp.p把结果以 HTML 形式吐回去。每个页面请求都在新会话里处理所以只有在渲染或处理页面那一刻才消耗数据库资源这也是它能在一台普通数据库服务器上撑住不少轻量应用的原因。这个HTTP 入口就是你安装时要做的选择题常见三种嵌入式 PL/SQL 网关EPG、基于 Apache 的 mod_plsql、独立的 APEX Listener。11g R1/R2 的 XDB 自带 EPGdbms_xdb.sethttpport一行就能开端口不用装 Apache、不用配 DAD 文件装完即用适合开发环境和内部系统代价是性能和并发能力有限真要上生产还得换独立监听器。10g 没有 EPG就只能走 mod_plsql 或独立监听器。这份资料里选的是 EPG我复现时也走的这条路本文所有步骤都以 EPG 为准。另一个绕不开的现实是版本。11g 出厂自带 APEX 3.0你要装 4.2.5 就必须先卸掉旧的否则同名同义词、老 schema 残留会一路把你带到登录失败上去。我的习惯是把整套东西装在虚拟机里装完挂起下次直接恢复省得再对着端口和目录结构重来一遍。2.2 卸载旧版本脚本跑完只是第一步官方给了卸载脚本但它只负责删对象不负责删干净用户。# 1) 以 SYS 身份跑官方卸载脚本清 APEX 3.0 的对象 cd $ORACLE_HOME/apex sqlplus / as sysdba apxdevrm.sql # 2) 清掉旧的 apex 目录内容避免版本混杂 cd $ORACLE_HOME/apex rm -rf *脚本跑完别急着往下走先查用户。3.0 的 schema 通常叫APEX_030200更早的还有FLOWS_030000如果dba_users里还有它们说明卸载没到根上。-- 确认是否还有旧版本 schema 残留 select username, account_status from dba_users where username like APEX% or username like FLOWS%; -- 残留的旧版本用户逐个清掉cascade 会连带对象一起删 drop user APEX_030200 cascade; -- 顺带看一眼有没有指向旧 schema 的失效同义词 select synonym_name, table_owner from dba_synonyms where table_owner like APEX% or table_owner like FLOWS%;这里的判断依据很简单APEX_030200可以删APEX_040200是你即将装出来的新引擎绝对不能删。我在第 5 章会专门讲误删的后果那是能让你重装一整天的操作。2.3 建表空间、解压、跑 apexinsAPEX 自己的元数据和索引建议单独放一个表空间别和生产业务表混在一起备份和迁移时你会感谢自己。CREATE TABLESPACE APEX01 DATAFILE /d01/oracle/ORCL/db/apps_st/data/apex01.dbf SIZE 100M AUTOEXTEND ON NEXT 100M MAXSIZE 1000M;数据文件路径按你库的实际目录改ORCL换成自己的实例名。然后解压安装包到$ORACLE_HOME下会得到一个apex目录再执行核心安装脚本。unzip -q apex_4.2.5.zip -d $ORACLE_HOME cd $ORACLE_HOME/apex # 四个参数APEX 表空间 / 文件与索引表空间 / 临时表空间 / 图片虚拟路径 sqlplus / as sysdba apexins.sql APEX01 APEX01 TEMP /i/四个参数必须说清楚。第一个是元数据表空间第二个放 BLOB 和索引第三个用默认临时表空间就行第四个/i/是静态图片的虚拟路径——它必须和后面apxldimg.sql加载图片时用的路径完全一致否则你会得到一堆 404 的图标和裸奔的页面。整个脚本执行十几到几十分钟不等中间是大量建表建包屏幕上刷过去的东西不用逐行看。2.4 设 ADMIN 密码、解锁公共用户、加载图片与中文-- 交互式修改 ADMIN 密码口令必须包含大写、小写、数字和特殊字符 apxchpwd.sql -- 两个公共账号必须解锁否则页面渲染直接报认证失败 ALTER USER ANONYMOUS ACCOUNT UNLOCK; ALTER USER APEX_PUBLIC_USER ACCOUNT UNLOCK; ALTER USER APEX_PUBLIC_USER IDENTIFIED BY Your_Str0ng_Pwd;APEX_PUBLIC_USER是 EPG 连库时用的账号密码改了之后要在 DAD 配置里同步apxconf.sql会帮你处理这一步。图片加载是新手最容易漏的一步漏了的表现是页面结构正常但全部无样式、图标变成裂图。# 把 images 灌进 XDB脚本会提示输入 ORACLE_HOME 路径 sqlplus / as sysdba apxldimg.sql # 可选加载简体中文界面 sqlplus / as sysdba builder/zh-cn/load_zh-cn.sql2.5 配置 EPG、端口与对外访问授权-- 创建 DAD 并把 /apex/* 映射到 APEX 引擎 apxconf.sql -- 确认端口8888 被占用时换一个 exec dbms_xdb.sethttpport(8888); commit; select dbms_xdb.gethttpport from dual;如果应用里要调外部 Web 服务11g 的网络 ACL 还得单独放行别指望默认能通-- 给 APEX 引擎 schema 放行外部主机访问 begin dbms_network_acl_admin.create_acl( acl apex_net.xml, description APEX outbound access, principal APEX_040200, is_grant true, privilege connect); commit; end; /访问http://server:8888/apex/apex_admin能出登录框http://server:8888/apex能出工作空间登录页基本就成了。如果 404先别怀疑安装按顺序查端口有没有真的改上去、DAD 有没有建、监听有没有重启。2.6 装完先过一遍验收清单检查项命令 / SQL期望结果EPG 端口select dbms_xdb.gethttpport from dual;返回 8888DAD 映射select * from dba_epg_dad_authorization;存在/apex/*的 DAD 记录APEX 版本select version_no from apex_release;4.2.x公共账号select username, account_status from dba_users where username in (APEX_PUBLIC_USER,ANONYMOUS);均为 OPEN图片资源select any_path from resource_view where any_path like /i/% and rownum 5;有记录返回这五条全绿再往下走后面所有问题都能排除环境没装好这个变量。3. Workspace 与账户模型四层身份、七种认证选错了后面全白干3.1 四层身份各管什么APEX 的权限模型第一次看容易糊其实就是四层顶层的ADMIN是超级管理员住在内部的 INTERNAL 工作空间里负责创建、删除、修改 Workspace 及其管理员下一层是 Workspace Admin管自己这个工作空间里的人和应用再往下是 Developer负责建页面写逻辑最末是 App End User只能跑应用。关键概念是 Workspace 和数据库 Schema 的对应关系。一个 Workspace 绑定一个 Schema可以理解成一个工程工程里可以有很多 Application。在和 ERP 套件集成时一个 Application 大致相当于一个 FormForm 里的多个窗口就是页面。所以绑定哪个 Schema直接决定了你在 SQL Workshop 里能看见哪些表、建的对象落在谁家里。3.2 建 Workspace 之前先把 Schema 准备好最省事的做法是让 APEX 自己建 Schema但接老系统时通常要复用已有的业务 Schema。两种都行前提是 Schema 里该有的权限得给足否则你在页面里写个 Process 就报权限不足。-- 独立 Schema 方案给 APEX 开发单独开一个用户别直接往生产 schema 灌对象 create user demo_ws identified by Your_Str0ng_Pwd default tablespace APEX01 quota unlimited on APEX01; grant create session, create table, create view, create procedure, create sequence, create trigger to demo_ws;创建 Workspace 时填这个 Schema 名系统会要求再设一个 Workspace 管理员账号。之后用管理员进 Workspace再建 Developer 和最终用户。三个角色别混用开发阶段图省事全用管理员登录到上线分配权限时一定返工。提示已经有生产 Schema 的情况下我更倾向在它下面建同义词或授权给 APEX 专用 Schema而不是让 APEX 直接登录生产 Schema。元数据表和业务表混在一起导出迁移时会非常难受。3.3 七种认证方案怎么挑创建 Application 时会让你三选一实际可选的认证方案一共有七种Application Express Accounts、Database Accounts、HTTP Header Variable、LDAP、Oracle SSO、Open Door、Custom。用得最多的是前两种和第三种。Application Express Accounts 是 APEX 自己的用户体系登录页由 APEX 生成用户名密码存在应用里适合内部开发、测试和用户量不大的管理端。Database Accounts 直接验证数据库用户好处是不用维护第二套账号坏处是数据库账号密码策略和 Web 端要求经常打架。HTTP Header Variable 是集成场景的常用解应用不接管登录只信任上游传过来的 header 里的用户名。ERP 套件挂一个 Function 指向 APEX 页面由套件侧注入当前登录工号用户点进去就是已登录状态不用二次输入。这个方案有个硬前提——header 只能由可信的内网入口注入如果客户端能直接构造请求就等于谁都能冒充任何人。所以只在内网入口做转发、APEX 不对外暴露时用它。3.4 Page 0全局项和全局常量的落脚点每个 Application 都有一个 0 号页叫全局页它在任何页面渲染之前执行页上定义的项在整个应用里都可见。用途很实在当前用户、当前日期、当前职责、一堆业务常量都可以在这里算好后面页面直接引用省得每个页面重复写计算。区域放在 Page 0 上是不会显示在界面上的效果类似 HTML 里的 hidden 字段。我一般会把不同类型的变量分区域放比如会话信息一个区域、业务常量一个区域日后排查这个值是哪来的能省很多时间。-- Page 0 上的计算项类型选 PL/SQL Function Body -- 计算点选 On New Instance每个新会话算一次 declare l_name varchar2(100); begin select login_name into l_name from demo_user_ctx where user_id :APP_USER; return l_name; exception when no_data_found then return :APP_USER; end;:APP_USER是 APEX 内置的绑定变量认证通过后自动有值。凡是页面上要用到当前登录人的地方都从这个计算项取别在每页各写一遍 SQL改起来是灾难。4. 页面布局与控件Grid Layout 的 TABLE/TR/TD 映射与 Dynamic Action 三件套4.1 主题定了布局的骨架就定了4.0 以后自带二十个左右的主题都符合 XHTML 和 CSS 标准页面可移植性更好、渲染也更快。选定主题后页面的整体布局和 CSS 基本已经定死它把若干常用槽位放开给开发者用Body1、Body2、Body3 和 Position1 到 Position4。其中 Body 系列在 HTML 里是以TABLE渲染的Position 系列是以DIV渲染的。这个区别非常重要直接决定了你的排版手段。想用表格对齐的就把区域挂在 Body 上想自由定位的挂 Position。我在 4.1.1 上做页面时最难受的一点是某个 Body 内的 Column 属性是全局的改一处影响一片。4.2.5 之后每个子区域都有独立的 Grid Layout 可以配这个问题才算解决所以版本尽量别停在 4.1。4.2 Grid Layout 三属性与 TABLE/TR/TD 的对应关系看懂这张对应表排版就不再是玄学Grid Layout 属性对应 HTML含义Start New Grid新的TABLE当前区域是否另起一张表不沿用上一个表格的列定义Start New RowTR当前区域是否换行ColumnTD序号当前区域落在本行的第几列Column Spancolspan跨几列4.2 才有一份能直接抄的配置Search1、Search2、Search3 放同一张表的一行Column 依次填 1、2、2Start New Grid 依次是 Yes、No、NoStart New Row 依次是 Yes、No、YesNew Search1、New Search2、New Search3 另起一张表Column 依次填 1、2、3Start New Grid 是 Yes、No、NoStart New Row 是 Yes、No、No。渲染出来的结构大致是这样对照着看就明白了!-- 第一张表Search 行第二列跨两格 -- table tr tdSearch1/td td colspan2Search2 Search3/td /tr /table !-- 第二张表New Search 行三等分 -- table tr tdNew Search1/td tdNew Search2/td tdNew Search3/td /tr /table配完刷新页面F12 看一眼 DOM是 table 还是 div、colspan 对不对比在后台反复猜快得多。复杂布局也是同一套原则堆出来的无非是嵌套区域再加一层 Grid。4.3 控件属性、事件、校验一份配置清单APEX 的控件文本框、下拉框、LOV、日期选择、报表本身没什么稀奇价值在属性面板上。几个高频属性值得记牢Form Element Width 控宽度Horizontal / Vertical Alignment 和 Label 位置管对齐Value Required 是必输Condition Type 控制满足条件才显示Read Only Condition Type 控制满足条件才只读Default Value 给默认值Format Mask 管日期和数字的格式掩码。这四类条件属性把大量本来要写 JS 的活变成了配置。事件侧靠 Dynamic Action核心是三个属性Condition Type 决定这个动作在什么前提下被考虑True Actions 和 False Actions 分别对应条件成立与不成立时干什么When Condition 再在事件触发后做一次判断。校验侧则是另一套When Button Pressed 指定由哪个按钮触发Condition Type 选Exists (SQL query returns at least one row)这类前置条件Condition Expression 写判定 SQLValidation Expression 写返回布尔的 PL/SQL 函数体Error message display location 和 Associated Item 决定错误信息显示在哪、关联到哪个字段。-- 校验前置条件要用到的表先建好并塞一条判定数据 create table demo_user_ctx( user_id varchar2(50) primary key, resp_id varchar2(50), resp_appl_id varchar2(50), login_name varchar2(50), login_count number, login_date date ); insert into demo_user_ctx values(123,,,,0,sysdate); commit;-- Validation 的表达式返回 true 表示校验通过 -- 只有在 demo_user_ctx 里存在 user_id123 时才触发这条校验 begin if :P2_X_TEXT is not null then return true; end if; return false; end;Condition Expression 里写select 1 from demo_user_ctx where user_id 123只有返回行才继续走后面的表达式。这个组合的实战意义是把校验的触发条件也数据化同一个页面在不同职责下走不同的校验规则不用改代码。4.4 两个 Dynamic Action 实例无刷新隐藏与页面加载赋值第一个是交互式的。需求是P2 上的文本框有值时隐藏 New Search2 区域为空时显示。事件定义Dynamic Action Name : DA_HIDE_NEW_SEARCH2 Event : Change Selection Type : Item(s) Item(s) : P2_X_TEXT Condition : is not null True Actions : Hide Region - New Search2 False Actions : Show Region - New Search2整个过程不发一次整页刷新体验接近现代前端框架而实现只是配置了几行。要注意 Condition 挂的位置挂在 Dynamic Action 层是事件触发前判断挂在 True/False Actions 里是事后分支两者行为不同配错了表现就是有时候管用有时候不管用。第二个是页面加载时给日期项赋当前日期。-- Set Value 动作的 SQL Statement结果写进 DATA 项 select sysdate from dual;事件定义 Name : DA_PAGE_LOAD_SET_DATE Event : Page Load Condition : No Condition True Action : Set Value Set Type : SQL Statement SQL Statement : select sysdate from dual; Selection Type : Item(s) Item(s) : DATA这类页面加载型动作在开发期非常好用能省掉一堆默认值计算。但要注意它在每次页面加载都会跑放在 Page 0 上就是每个页面都跑别在里面写重查询。4.5 Tabular Form基于视图的多行增删改与 Process 逻辑常规做法是一条记录跳一个新页面去改Tabular Form 则是在一个表格里对多行同时增删改思路和 ERP 的 Form 块很像——底层基于视图开发。视图负责把要展示的多个表字段拼成一行页面上的列和视图列一一对应。-- 班级查找表 create table demo_class( class_id number primary key, class_name varchar2(50) ); -- 展示视图把用户和班级拼在一起 -- 注意多表 join 的视图默认不可更新需要 INSTEAD OF 触发器兜住 DML create or replace view v_demo_class_user as select u.user_id, u.login_name, u.resp_id, c.class_id, c.class_name from demo_user_ctx u, demo_class c where c.class_id u.resp_id; create or replace trigger trg_v_demo_class_user instead of update on v_demo_class_user begin update demo_user_ctx set login_name :new.login_name where user_id :new.user_id; end; /页面侧先建一个基于该视图的 Tabular Form 区域再建一个Apply Change按钮然后在按钮上挂 Process处理改登录名和校验班级是否存在这两件事。多行一起提交时页面上的数据是通过apex_application.g_f01到g_fNN这组数组传到后台的g_f01通常是行选择器复选框后面依次对应各列编号跟着列顺序走。declare l_exists number; l_class varchar2(50); begin -- g_f01 是行选择器g_f03/g_f05 对应视图里的 login_name / class_name 列 for i in 1 .. nvl(apex_application.g_f01.count, 0) loop if apex_application.g_f01(i) is not null then l_class : apex_application.g_f05(i); select count(*) into l_exists from demo_class where class_name l_class; if l_exists 0 then apex_error.add_error( p_message l_class || 不在班级表中请先维护, p_display_location apex_error.c_inline_with_field_and_notif, p_page_item_name ); end if; end if; end loop; end;逻辑说明两点。第一循环上界必须用nvl(..., 0)没有勾选任何行时count为 0直接for i in 1..count在某些版本上会抛异常。第二g_f0x的编号是位置编号不是列名编号你在 Tabular Form 中间插一列后面所有编号整体后移昨天还能跑的 Process 今天就会读错字段——这是我在这个功能上翻车最多的地方改列顺序时一定要回头对一遍 Process。校验通过后要写回另一张表的就在同一个循环里追加 insert或者用一个独立的 Process把When Button Pressed设成APPLY_CHANGE靠按钮控制执行时机别指望页面一提交就执行。5. 避坑排查五条现象、原因和收尾动作5.1 ADMIN 密码改了三遍还是登不上现象apex_admin页面输入 ADMIN 和新密码提示无效登录改密码、重启数据库、重装前端都无效。原因库里还留着 3.0 时代的 schema 和同义词登录校验链路走到旧对象上去了。这种情况在卸载不彻底直接覆盖安装之后出现概率极高。解决先确认残留再清理最后重设密码。select username from dba_users where username like APEX% or username like FLOWS%; -- 确认是旧版本用户后 drop user APEX_030200 cascade; -- 回到 $ORACLE_HOME/apex 重设管理员口令 apxchpwd.sql5.2 手滑 drop 掉新引擎 schema整站全挂现象所有 APEX 页面报 ORA-00942 或直接 500数据库里其他应用不受影响。原因APEX_040200不是普通用户它就是引擎本身应用的元数据、页面定义、图片引用全在里面。执行drop user APEX_040200 cascade等于把引擎连数据一起删了而且这个操作没有后悔药。解决只能重跑apexins.sql重建引擎。重建后引擎能活但之前做的应用和页面数据找不回来——除非你之前导出过应用Application 级别的导出脚本。所以我的固定动作是任何涉及drop user的操作之前先把应用导出成 SQL 脚本存一份哪怕只是开发环境。5.3 页面能打开但样式全丢、图标全裂现象登录进工作空间HTML 结构正常CSS 完全没生效浏览器控制台一堆/i/...的 404。原因apxldimg.sql没跑或者跑的时候输入的ORACLE_HOME路径不对又或者apexins.sql的图片虚拟路径参数和实际加载路径不一致。解决重跑图片加载脚本输入正确的ORACLE_HOME然后确认 XDB 里资源真的存在。cd $ORACLE_HOME/apex sqlplus / as sysdba apxldimg.sqlselect any_path from resource_view where any_path like /i/% and rownum p a hrefhttps://download.csdn.net/download/hero_518/7742009 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p
阅读完成 · 觉得有帮助?