在 Oracle EBS 的二次开发和运维中,还原 LOV(值列表) 的底层 SQL 是基本功。虽然常用的 SYSTEM.LAST_QUERY 比较方便,但它存在严重的长度限制(容易被截断),且在某些复杂 Form 或动态 Record Group 场景下无法捕获。
本文分享一个“全场景”解决方案:锁定会话 SID,配合 PL/SQL 脚本从数据库内存中提取最完整的 SQL 语句。
🛠️ 第一步:获取当前会话的 SID(两种有效方法)
在执行脚本前,我们需要获取当前窗口对应的数据库 Session SID。
方法 A:通过“关于”界面查看(首选,最快)
在大多数情况下,直接查看系统信息是最直接的方式:
在目标界面点击菜单:帮助 (Help) > 关于 Oracle Applications (About Oracle Applications)。
在弹出的窗口中向下滚动至 Database Server 区域。
记录下 Session SID(例如:
426)。

方法 B:通过个性化测试获取(备选,应对特殊场景)
当界面无法通过“关于”直接看到 SID 时,我们可以利用 Form Personalization(表单个性化) 弹窗来获取:
逻辑代码:
=(SELECT t.sid FROM v$mystat t where rownum = 1)。适用场景: 虽然直接查看界面更快,但当标准界面无法直接查看到 SID 时,该方法是完美的替代方案。

⚠️ 技术纠错:关于 Examine 工具
经过实测证明,在 Help > Diagnostics > Examine(检查)工具中,SYSTEM 块下的变量列表里并不包含 SESSION_ID 字段。因此,请务必使用上述两种有效途径获取。
💻 第二步:执行抓取脚本(关键操作点)
拿到 SID 后,在 SQL 工具(如 PLSQL Developer)中以 APPS 身份运行以下脚本。
🚨 核心注意点(必看!)
在数据库执行以下查询语法前,请务必确保:
保持打开 LOV:在 EBS 界面中已经点击弹出 LOV 窗口。
已经查出值:在 LOV 中输入
%或特定字符并点击查询,确保结果列表已经显示。不要关闭窗口:在执行数据库脚本的过程中,必须保持该值列表处于打开状态。如果关闭了 LOV 窗口,会话状态可能会发生变化,导致抓取不到正确的SQL。

declare
cursor cur_lov_sql(p_pre_sql_addr varchar2) is
select t.SQL_TEXT
from v$sqltext_with_newlines t
where t.ADDRESS = p_pre_sql_addr
order by t.PIECE;
--
l_lov_sql varchar2(2400);
l_prev_sql_addr varchar2(200);
begin
begin
select v.PREV_SQL_ADDR
into l_prev_sql_addr
from v$session v
where v.SID = &sid;
exception
when others then
dbms_output.put_line('get prev sql addr error,'||sqlcode||':'||sqlerrm);
end;
--
for rec in cur_lov_sql(l_prev_sql_addr) loop
l_lov_sql := nvl(l_lov_sql,'')||rec.sql_text;
end loop;
--
dbms_output.put_line('lov查询sql为:');
dbms_output.put_line(l_lov_sql);
end;
🌟 总结
状态保持:抓取 SQL 的那一刻,LOV 必须是“活跃”且“展开”的。
突破限制:通过
v$sqltext拼接可以抓取变态长的 SQL,不再担心截断问题。灵活应对:掌握了“关于”界面与“个性化”两种方式,足以应对各种复杂的运维环境。
标签:#OracleEBS #SQL技巧 #LiaoDev #ERP运维 #PLSQL实战
评论区