调用Oracle存储过程遇ORA-06550/PLS-00306错误求助
排查C#调用Oracle包存储过程时的ORA-06550/PLS-00306参数不匹配问题
以下是针对该错误的核心排查方向,按优先级排序:
1. 确认参数绑定顺序与模式
Oracle存储过程默认按位置匹配参数,哪怕参数名称一致,顺序错误也会触发类型/数量不匹配报错:
- 若使用命名参数绑定,必须显式设置
OracleCommand.BindByName = true,否则仍按位置解析 - 检查存储过程的参数模式(
IN/OUT/IN OUT):C#中必须对应设置ParameterDirection,例如OUT参数不能默认用Input模式
示例正确绑定方式:
cmd.BindByName = true; // IN参数 cmd.Parameters.Add("p_id", OracleDbType.Int32).Value = 123; // OUT参数 cmd.Parameters.Add("p_out_code", OracleDbType.Varchar2, 10).Direction = ParameterDirection.Output;
2. 核对数据类型精确匹配
避免C#与Oracle类型的隐式转换失误:
- 数值类型:Oracle
NUMBER(10,2)对应C#decimal,NUMBER(5)对应int,不要用float或double替代 - 字符类型:Oracle
VARCHAR2(50)需指定C#参数长度,避免超长截断;NVARCHAR2对应OracleDbType.NVarchar2 - 日期类型:直接传入
DateTime对象,不要用字符串拼接TO_DATE,避免格式/时区问题 - 特殊类型:Oracle
BOOLEAN无直接C#对应类型,需用OracleDbType.Boolean或映射为NUMBER(1)(1=true/0=false)
3. 检查存储过程重载与权限
- 若包内存在同名重载存储过程,需确保C#参数完全匹配目标重载的参数数量、类型与模式
- 确认执行用户拥有
EXECUTE权限:执行GRANT EXECUTE ON TAPK_ICPREC_DATA TO 你的数据库用户;
4. 验证包定义与调用语句
确保C#中调用的存储过程全名正确:
// 正确格式:包名.存储过程名 cmd.CommandText = "TAPK_ICPREC_DATA.tapp_main_insert"; cmd.CommandType = CommandType.StoredProcedure;
不要在语句中添加BEGIN/END包裹(除非用匿名块调用)
若以上排查仍未解决,请补充以下信息:
- 完整的Oracle包定义(
CREATE OR REPLACE PACKAGE代码) - 存储过程
tapp_main_insert的参数列表 - 你的C#参数绑定代码片段
内容的提问来源于stack exchange,提问作者Csharp
相关产品推荐
相关产品推荐

