开发环境
| 名称 | 版本 |
|---|---|
| 操作系统 | Windows 10 X64 |
| Oracle | win64_11gR2_database |
| PLSQL Developer | 11.0.4.1788(64 bit)01.179332 - Unlimited user license |
问题描述
- 测试环境操作某一个功能,报如下错误
nested exception is org.apache.ibatis.exceptions.PersistenceException:### Error querying database. Cause: java.lang.reflect.UndeclaredThrowableException### The error may exist in file [/home/luoma-receipt-server/conf/mapper/CommonButtonPersistent.xml]### The error may involve com.luoma.oa.fm.etms.receipt.server.job.persistent.CommonButtonPersistent.preGL-Inline### The error occurred while setting parameters### 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 => ? )}### Cause: java.lang.reflect.UndeclaredThrowableException
- 但是我本地没有报错,于是把此 sql 在测试环境数据库执行
declarep_Return_Status varchar2(100);p_Msg_Count number;p_Msg_Data varchar2(4000);p_Interface_Cnt number;beginuser1.cux_ce_ard_pkg.Pre_Gl(p_Init_Msg_List => 'T',p_Commit => 'T',x_Return_Status => p_Return_Status,x_Msg_Count => p_Msg_Count,x_Msg_Data => p_Msg_Data,x_Interface_Cnt => p_Interface_Cnt,p_Import_Mode => 'M',p_Batch_Id => 214734,p_User_Id => 10728);dbms_output.put_line('*****************');dbms_output.put_line('x_Return_Status:' || p_Return_Status);dbms_output.put_line('x_Msg_Count:' || p_Msg_Count);dbms_output.put_line('x_Msg_Data:' || p_Msg_Data);dbms_output.put_line('x_Interface_Cnt:' || p_Interface_Cnt);end;
报错
ORA-06550:line 7. column 3:PLS-00306: wrong number or types of arguments in call to 'PRE GL'ORA-06550: line 7, column 3:PL/SQL: Statement ignoredORA-06550:第7行第3列:PLS-00306: 调用'PRE GL' 时参数个数或类型错误ORA-06550:第7行第3列:PL/SQL: Statement ignored
问题分析
- 我本机无论是程序调用还是数据库调用,都是正常的。
- 在测试环境数据库中
user1.cux_ce_ard_pkg.Pre_Glsql 部分按住Ctrl+鼠标左键,进入定义,发现定义如下。
Procedure Pre_Gl(p_Init_Msg_List In Varchar2 Default Fnd_Api.g_False,p_Commit In Varchar2 Default Fnd_Api.g_False,x_Return_Status Out Nocopy Varchar2,x_Msg_Count Out Nocopy Number,x_Msg_Data Out Nocopy Varchar2,x_Interface_Cnt Out Nocopy Number,p_Import_Mode In Varchar2,p_Batch_Id In Number);
- 开发环境数据库中
user1.cux_ce_ard_pkg.Pre_Glsql 部分按住Ctrl+鼠标左键,进入定义,发现定义如下。
Procedure Pre_Gl(p_Init_Msg_List In Varchar2 Default Fnd_Api.g_False,p_Commit In Varchar2 Default Fnd_Api.g_False,x_Return_Status Out Nocopy Varchar2,x_Msg_Count Out Nocopy Number,x_Msg_Data Out Nocopy Varchar2,x_Interface_Cnt Out Nocopy Number,p_Import_Mode In Varchar2,p_Batch_Id In Number,p_User_Id In Number Default 0)
- 测试环境数据库中,我新添加的参数
p_User_Id并没有生效,但是明明已经执行成功了的呀?
问题原因
问题的原因在于,有两个用户拥有这个包
cux_ce_ard_pkg。查询这个包的拥有者
-- 查询包的所有者SELECT OWNER, OBJECT_NAME, OBJECT_TYPEFROM DBA_OBJECTSWHERE 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:但是我之前发布到生产环境都是没有指定用户的,后面查询生产环境的包拥有者,发现只有一个用户,所以之前没有指定也是没问题的。
-- 查询包的所有者SELECT OWNER, OBJECT_NAME, OBJECT_TYPEFROM DBA_OBJECTSWHERE OBJECT_TYPE = 'PACKAGE' AND OBJECT_NAME = 'CUX_CE_ARD_PKG';
- 结果如下
| OWNER | OBJECT_NAME | OBJECT_TYPE |
|---|---|---|
| USER1 | CUX_CE_ARD_PKG | OBJECT_TYPE |
问题解决
1.如果有多个用户拥有此包,则切换到对应用户都要执行一遍这个包的创建代码,否则就会出现不一致的情况导致调用报错。
2.创建时指定用户,例如
CREATE OR REPLACE Package User1.Cux_Ce_Ard_Pkg Is