Oracle-同一个包被不同用户拥有导致调用报错的问题

2024年09月09日 10:05 · 阅读(249) ·

开发环境

名称 版本
操作系统 Windows 10 X64
Oracle win64_11gR2_database
PLSQL Developer 11.0.4.1788(64 bit)01.179332 - Unlimited user license

问题描述

  • 测试环境操作某一个功能,报如下错误
  1. nested exception is org.apache.ibatis.exceptions.PersistenceException:
  2. ### Error querying database. Cause: java.lang.reflect.UndeclaredThrowableException
  3. ### The error may exist in file [/home/luoma-receipt-server/conf/mapper/CommonButtonPersistent.xml]
  4. ### The error may involve com.luoma.oa.fm.etms.receipt.server.job.persistent.CommonButtonPersistent.preGL-Inline
  5. ### The error occurred while setting parameters
  6. ### SQL: {call user1.cux_ce_ard_pkg.Pre_Gl (p_Init_Msg_List => 'T', p_Commit => 'T', x_Return_Status => ?, x_Msg_Count => ?, x_Msg_Data => ?, x_Interface_Cnt => ?, p_Import_Mode => ?, p_Batch_Id => ?, p_User_Id => ? )}
  7. ### Cause: java.lang.reflect.UndeclaredThrowableException
  • 但是我本地没有报错,于是把此 sql 在测试环境数据库执行
  1. declare
  2. p_Return_Status varchar2(100);
  3. p_Msg_Count number;
  4. p_Msg_Data varchar2(4000);
  5. p_Interface_Cnt number;
  6. begin
  7. user1.cux_ce_ard_pkg.Pre_Gl
  8. (p_Init_Msg_List => 'T',
  9. p_Commit => 'T',
  10. x_Return_Status => p_Return_Status,
  11. x_Msg_Count => p_Msg_Count,
  12. x_Msg_Data => p_Msg_Data,
  13. x_Interface_Cnt => p_Interface_Cnt,
  14. p_Import_Mode => 'M',
  15. p_Batch_Id => 214734,
  16. p_User_Id => 10728
  17. );
  18. dbms_output.put_line('*****************');
  19. dbms_output.put_line('x_Return_Status:' || p_Return_Status);
  20. dbms_output.put_line('x_Msg_Count:' || p_Msg_Count);
  21. dbms_output.put_line('x_Msg_Data:' || p_Msg_Data);
  22. dbms_output.put_line('x_Interface_Cnt:' || p_Interface_Cnt);
  23. end;

报错

  1. ORA-06550:line 7. column 3:
  2. PLS-00306: wrong number or types of arguments in call to 'PRE GL'
  3. ORA-06550: line 7, column 3:
  4. PL/SQL: Statement ignored
  5. ORA-06550:第7行第3列:
  6. PLS-00306: 调用'PRE GL' 时参数个数或类型错误
  7. ORA-06550:第7行第3列:
  8. PL/SQL: Statement ignored

问题分析

  • 我本机无论是程序调用还是数据库调用,都是正常的。
  • 在测试环境数据库中 user1.cux_ce_ard_pkg.Pre_Gl sql 部分按住 Ctrl + 鼠标左键,进入定义,发现定义如下。
  1. Procedure Pre_Gl(p_Init_Msg_List In Varchar2 Default Fnd_Api.g_False,
  2. p_Commit In Varchar2 Default Fnd_Api.g_False,
  3. x_Return_Status Out Nocopy Varchar2,
  4. x_Msg_Count Out Nocopy Number,
  5. x_Msg_Data Out Nocopy Varchar2,
  6. x_Interface_Cnt Out Nocopy Number,
  7. p_Import_Mode In Varchar2,
  8. p_Batch_Id In Number);
  • 开发环境数据库中 user1.cux_ce_ard_pkg.Pre_Gl sql 部分按住 Ctrl + 鼠标左键,进入定义,发现定义如下。
  1. Procedure Pre_Gl(p_Init_Msg_List In Varchar2 Default Fnd_Api.g_False,
  2. p_Commit In Varchar2 Default Fnd_Api.g_False,
  3. x_Return_Status Out Nocopy Varchar2,
  4. x_Msg_Count Out Nocopy Number,
  5. x_Msg_Data Out Nocopy Varchar2,
  6. x_Interface_Cnt Out Nocopy Number,
  7. p_Import_Mode In Varchar2,
  8. p_Batch_Id In Number,
  9. p_User_Id In Number Default 0)
  • 测试环境数据库中,我新添加的参数 p_User_Id 并没有生效,但是明明已经执行成功了的呀

问题原因

  • 问题的原因在于,有两个用户拥有这个包 cux_ce_ard_pkg

  • 查询这个包的拥有者

  1. -- 查询包的所有者
  2. SELECT OWNER, OBJECT_NAME, OBJECT_TYPE
  3. FROM DBA_OBJECTS
  4. WHERE OBJECT_TYPE = 'PACKAGE' AND OBJECT_NAME = 'CUX_CE_ARD_PKG';
  • 结果如下
OWNER OBJECT_NAME OBJECT_TYPE
USER1 CUX_CE_ARD_PKG OBJECT_TYPE
USER2 CUX_CE_ARD_PKG OBJECT_TYPE
  • 开发环境使用 user1.cux_ce_ard_pkg.Pre_Gl 按住 Ctrl + 鼠标左键,进入定义,发现定义是最新的定义。
  • 测试环境使用 user2.cux_ce_ard_pkg.Pre_Gl 按住 Ctrl + 鼠标左键,进入定义,发现定义是最新的定义。
  • 测试环境使用 user1.cux_ce_ard_pkg.Pre_Gl 按住 Ctrl + 鼠标左键,进入定义,发现定义是旧的定义。

  • 由于我开发环境始终都是使用 user1 用户进行操作,所以没有报错。

  • 但是测试环境是使用 user2 执行的包创建语句。但是使用 user1 进行调用,导致调用代码中多出来的参数没有匹配到最新的定义,导致报错。

PS:但是我之前发布到生产环境都是没有指定用户的,后面查询生产环境的包拥有者,发现只有一个用户,所以之前没有指定也是没问题的。

  1. -- 查询包的所有者
  2. SELECT OWNER, OBJECT_NAME, OBJECT_TYPE
  3. FROM DBA_OBJECTS
  4. WHERE OBJECT_TYPE = 'PACKAGE' AND OBJECT_NAME = 'CUX_CE_ARD_PKG';
  • 结果如下
OWNER OBJECT_NAME OBJECT_TYPE
USER1 CUX_CE_ARD_PKG OBJECT_TYPE

问题解决

  • 1.如果有多个用户拥有此包,则切换到对应用户都要执行一遍这个包的创建代码,否则就会出现不一致的情况导致调用报错。

  • 2.创建时指定用户,例如

  1. CREATE OR REPLACE Package User1.Cux_Ce_Ard_Pkg Is

相关问题

Oracle-不同用户下的视图导致查询结果不一样的问题