You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apex升级至23.1.5后报表抛出ORA-01445错误求助

问题:Apex升级至23.1.5后报表抛出ORA-01445错误

报表错误:
ORA-01445: cannot select ROWID from, or sample, a join view without a key-preserved table

将Apex升级到23.1.5版本后,一款此前运行正常的报表应用突然抛出上述错误。该模块用于展示数据,升级过程中未修改任何应用代码或配置,预期应用能保持升级前的运行状态。

后台查询代码如下:

SELECT s."ROWID",
  s."EMPLOYEE_NUMBER",
  NVL(p.full_name, 'Invalid') FULLNAME,
  s."DOCUMENT_TYPE",
  s."COST_CENTRE_PARENT",
  s."SIGNING_LIMIT",
  l.name ledger,
  a.organization_id
FROM "#OWNER#".xxapex142_signing_limits s
  , apps.per_all_people_f p
  , apps.per_all_assignments_f a
  , apps.gl_ledgers l
WHERE s.employee_number = p.employee_number (+)
 AND  p.person_id = a.person_id (+)
 AND  a.set_of_books_id = l.ledger_id (+)
 AND  l.short_name = 'DJR_PRIMARY'
 AND (
   UPPER(s.employee_number) LIKE '%'||NVL(UPPER(:P2_SEARCH_TEXT),'')||'%'
OR UPPER(p.full_name) LIKE '%'||NVL(UPPER(:P2_SEARCH_TEXT),'')||'%'
OR UPPER(s.cost_centre_parent) LIKE '%'||NVL(UPPER(:P2_SEARCH_TEXT),'')||'%'
OR UPPER(s.signing_limit) LIKE '%'||NVL(UPPER(:P2_SEARCH_TEXT),'')||'%'
OR UPPER(a.organization_id) LIKE '%'||NVL(UPPER(:P2_SEARCH_TEXT),'')||'%'
OR UPPER(l.name) LIKE '%'||NVL(UPPER(:P2_SEARCH_TEXT),'')||'%'
)
解决方案

错误原因

ORA-01445错误的核心是:查询直接从多表连接的结果集中选择ROWID,但该结果集里没有Oracle认定的「键保留表」——也就是无法保证主表的每一行在连接后只出现一次,Oracle无法安全返回ROWID。Apex 23.1.5对报表查询的ROWID使用规则做了更严格的校验,升级前版本可能允许这种不规范写法,升级后触发了Oracle本身的约束检查。

修复步骤

1. 移除不必要的ROWID查询

如果报表不需要用ROWID做编辑、删除等操作,直接删掉SELECT列表中的s."ROWID"即可:

SELECT s."EMPLOYEE_NUMBER",
  NVL(p.full_name, 'Invalid') FULLNAME,
  s."DOCUMENT_TYPE",
  s."COST_CENTRE_PARENT",
  s."SIGNING_LIMIT",
  l.name ledger,
  a.organization_id
FROM "#OWNER#".xxapex142_signing_limits s
  , apps.per_all_people_f p
  , apps.per_all_assignments_f a
  , apps.gl_ledgers l
WHERE s.employee_number = p.employee_number (+)
 AND  p.person_id = a.person_id (+)
 AND  a.set_of_books_id = l.ledger_id (+)
 AND  l.short_name = 'DJR_PRIMARY'
 AND (
   UPPER(s.employee_number) LIKE '%'||NVL(UPPER(:P2_SEARCH_TEXT),'')||'%'
OR UPPER(p.full_name) LIKE '%'||NVL(UPPER(:P2_SEARCH_TEXT),'')||'%'
OR UPPER(s.cost_centre_parent) LIKE '%'||NVL(UPPER(:P2_SEARCH_TEXT),'')||'%'
OR UPPER(s.signing_limit) LIKE '%'||NVL(UPPER(:P2_SEARCH_TEXT),'')||'%'
OR UPPER(a.organization_id) LIKE '%'||NVL(UPPER(:P2_SEARCH_TEXT),'')||'%'
OR UPPER(l.name) LIKE '%'||NVL(UPPER(:P2_SEARCH_TEXT),'')||'%'
)

2. 若需唯一标识,改用业务主键

如果报表需要唯一标识用于后续操作,直接用s."EMPLOYEE_NUMBER"(假设该字段是xxapex142_signing_limits表的主键)替代ROWID,或者明确指定表的主键字段。

3. 确保连接结果存在键保留表

如果必须保留ROWID,需调整查询逻辑:

  • 确认s.employee_number是xxapex142_signing_limits表的主键或唯一约束,保证主表每行唯一
  • 调整外连接逻辑,避免其他表的多行数据匹配到主表同一行

额外建议

  • 升级Apex后,检查所有报表的ROWID使用情况,提前规避类似问题
  • 多表连接查询中优先用业务主键,尽量避免直接使用ROWID

内容的提问来源于stack exchange,提问作者John T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 06:08:17