开发环境
名称 | 版本 |
---|---|
操作系统 | 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 在测试环境数据库执行
declare
p_Return_Status varchar2(100);
p_Msg_Count number;
p_Msg_Data varchar2(4000);
p_Interface_Cnt number;
begin
user1.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 ignored
ORA-06550:第7行第3列:
PLS-00306: 调用'PRE GL' 时参数个数或类型错误
ORA-06550:第7行第3列:
PL/SQL: Statement ignored
问题分析
- 我本机无论是程序调用还是数据库调用,都是正常的。
- 在测试环境数据库中
user1.cux_ce_ard_pkg.Pre_Gl
sql 部分按住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_Gl
sql 部分按住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_TYPE
FROM DBA_OBJECTS
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:但是我之前发布到生产环境都是没有指定用户的,后面查询生产环境的包拥有者,发现只有一个用户,所以之前没有指定也是没问题的。
-- 查询包的所有者
SELECT OWNER, OBJECT_NAME, OBJECT_TYPE
FROM DBA_OBJECTS
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.创建时指定用户,例如
CREATE OR REPLACE Package User1.Cux_Ce_Ard_Pkg Is