侧边栏壁纸
博主头像
LiaoDev's Blog 博主等级

行动起来,活在当下

  • 累计撰写 7 篇文章
  • 累计创建 0 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

[Oracle EBS] 排查笔记:CCID 组合存在但 validate_segs 验证失败

luke
2026-01-27 / 0 评论 / 0 点赞 / 12 阅读 / 0 字

发布时间: 2026-01-27

分类: Oracle EBS, PL/SQL, 问题排查

问题背景

最近在开发一个接口时,需要根据给定的段值组合(Segments)获取对应的 CODE_COMBINATION_ID (CCID)。如果组合不存在,则自动创建。

我使用了标准的 API fnd_flex_keyval.validate_segs 进行校验,操作模式为 CREATE_COMBINATION

遇到的怪事是:

我传入的组合字符串在数据库表 gl_code_combinations 中明明是存在的,且 ENABLED_FLAGY。但是,PL/SQL 代码运行后,validate_segs API 始终返回 FALSE(验证失败),无法获取 CCID。

排查过程

1. 初始代码测试

最初的代码如下(已脱敏),执行后直接进入 ELSE 分支:

SQL

DECLARE
  lb_result BOOLEAN;
  ln_ccid   NUMBER;
BEGIN
  -- 模拟传入一个已知的组合字符串
  lb_result := fnd_flex_keyval.validate_segs(
      operation        => 'CREATE_COMBINATION',
      appl_short_name  => 'SQLGL',
      key_flex_code    => 'GL#',
      structure_number => '50368',  -- 对应的 COA ID
      concat_segments  => 'XX.XXXX.XXXXXX.0.0.0.XXXX.0' -- 已脱敏的组合
  );

  IF lb_result THEN
    ln_ccid := fnd_flex_keyval.combination_id;
    dbms_output.put_line('Success! CCID: ' || ln_ccid);
  ELSE
    dbms_output.put_line('Failed to validate segments.');
  END IF;
END;

输出结果: Failed to validate segments.

2. 检查数据库数据

第一反应是数据有问题。我去查询了 gl_code_combinations 表:

SQL

SELECT code_combination_id, enabled_flag, start_date_active, end_date_active
  FROM gl_code_combinations_kfv
 WHERE concatenated_segments = 'XX.XXXX.XXXXXX.0.0.0.XXXX.0';

查询结果:

  • CODE_COMBINATION_ID: 9xxxx

  • ENABLED_FLAG: Y

  • END_DATE_ACTIVE: NULL

疑惑点: 组合明明是“启用”状态,为什么 API 说它无效?

3. 获取详细报错信息

Oracle 的 API 不会无缘无故报错。我在代码中加入了一行打印错误堆栈的语句,这是破案的关键:

SQL

DECLARE
  lb_result BOOLEAN;
  ln_ccid   NUMBER;
  l_err_msg VARCHAR2(2000); -- 定义错误信息变量
BEGIN
  -- 1. (可选) 如果涉及安全性,建议先初始化
  -- fnd_global.apps_initialize(user_id => xxxx, resp_id => xxxx, resp_appl_id => 101);

  -- 2. 调用 API
  lb_result := fnd_flex_keyval.validate_segs(operation        => 'CREATE_COMBINATION', -- 尝试改为 'FIND_COMBINATION' 试试
                                             appl_short_name  => 'SQLGL',
                                             key_flex_code    => 'GL#',
                                             structure_number => '50368',
                                             concat_segments  => 'XX.XXXX.XXXXXX.0.0.0.XXXX.0');

  IF lb_result THEN
    ln_ccid := fnd_flex_keyval.combination_id;
    dbms_output.put_line('成功获取 CCID: ' || ln_ccid);
  ELSE
    -- 3. 【核心】获取并打印错误堆栈
    l_err_msg := fnd_flex_keyval.error_message;
    dbms_output.put_line('------------------------------');
    dbms_output.put_line('API 返回失败,具体原因如下:');
    dbms_output.put_line(l_err_msg);
    dbms_output.put_line('------------------------------');
  
    -- 有时错误在 encoded_error 中
    dbms_output.put_line('原始错误代码: ' ||
                         fnd_flex_keyval.encoded_error_message);
  END IF;
END;

再次运行,控制台打印出了具体的错误原因:

Error Message: Value XXXXXX has been disabled.

4. 根源分析

看到报错信息瞬间明白了。这里存在一个概念误区:

  • 组合状态 (Combination Status)gl_code_combinations 表里的 ENABLED_FLAG 指的是这个“整体组合”是否被禁用。

  • 段值状态 (Segment Value Status):组合里的每一个段(公司、部门、科目等)都有自己的独立状态。

结论: 虽然这个会计科目组合整体是 Y,但其中有一个具体的“科目段”值(XXXXXX)在值集定义中被禁用了(Disabled)。

validate_segs API 执行的是严格的业务校验,只要任何一个子段不可用,整个组合的验证就会失败。

5. 验证与修复

我去查询了 fnd_flex_values_vl 表,确实发现该段值的 ENABLED_FLAGN

修复步骤:

  1. 登录 Oracle EBS 系统。

  2. 路径:总帐 > 设置 > 财务系统 > 弹性域 > >

  3. 找到对应的值集,查询出问题的值 XXXXXX

  4. 发现“启用 (Enabled)”复选框确实未勾选。

  5. 勾选启用并保存

最终结果

在前端界面重新启用该段值后,再次运行 PL/SQL 脚本,lb_result 返回 TRUE,成功获取到了 CCID。

经验总结

  1. 存在 <> 有效:表里查得到数据,不代表该数据在业务上是合法的。

  2. API 报错信息很重要:调用标准 API 失败时,一定要打印 error_messageencoded_error_message,不要只打印“失败了”。

  3. 层级关系:排查 COA 问题时,不仅要看组合层级,还要下钻看具体的 Segment Value 层级。

0

评论区