oracleexception.errorcode 是 oracle 数据提供程序抛出的只读整数属性,直接对应 oracle 原生错误号(如 ora-00942 → 942),是判断数据库端问题最可靠的依据;必须显式 catch oracleexception 才能安全访问,其值恒为正整数,稳定可移植,远优于依赖 message 字符串匹配。

OracleException.ErrorCode 是什么
OracleException.ErrorCode 是 Oracle 数据提供程序(ODP.NET)抛出的 OracleException 实例中一个只读整数属性,它直接对应 Oracle 数据库返回的原生错误号(如 ORA-00942 对应 ErrorCode = 942)。它不是 .NET 的 Exception.HResult,也不等同于 SQL Server 的 SqlException.Number —— 它专属于 Oracle 驱动层,是判断数据库端具体问题最可靠的依据。
如何在 catch 块中安全获取并判断 ErrorCode
必须先确认异常类型是 OracleException,再访问 ErrorCode;否则强制转型或直接访问会抛出 InvalidCastException 或 NullReferenceException。常见错误写法是只 catch Exception 然后硬转,这会导致漏判或崩溃。
- 用
catch (OracleException ex)显式捕获,是最安全、最推荐的方式 - 如果上层已统一用
catch (Exception ex),需先用ex is OracleException oraEx判断,再安全解构 -
ErrorCode值始终为正整数(如表不存在是 942,权限不足是 1031),不会是负数或 0 - 不要依赖
ex.Message做逻辑分支——消息内容可能被本地化或截断,而ErrorCode稳定、可移植
示例:
try
{
using (var conn = new OracleConnection(connStr))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT * FROM non_existent_table";
cmd.ExecuteNonQuery();
}
}
}
catch (OracleException ex) when (ex.ErrorCode == 942)
{
Console.WriteLine("表不存在,跳过处理");
}
catch (OracleException ex) when (ex.ErrorCode == 1031)
{
Console.WriteLine("缺少执行权限,请联系 DBA");
}
catch (OracleException ex)
{
Console.WriteLine($"未预期的 Oracle 错误 {ex.ErrorCode}: {ex.Message}");
}
常见 OracleErrorCode 及典型场景
不是所有错误码都需要单独处理,但几个高频码值得硬编码识别:
-
942:表或视图不存在(ORA-00942)——适合做“自动建表”或降级逻辑的触发点 -
1:违反唯一约束(ORA-00001)——常用于幂等插入(忽略重复)、提示用户重试 -
1403:未找到数据(ORA-01403)——SELECT INTO无结果时抛出,不同于普通空结果集 -
1031:权限不足(ORA-01031)——应记录并通知运维,而非重试 -
2292:违反外键约束(ORA-02292)——删除主记录前需先清理子记录
注意:OracleException 的 Source 属性通常为 "Oracle Data Provider for .NET",可辅助确认异常来源;但不能替代 ErrorCode 做业务决策。
为什么不能只靠 try-catch(Exception) + Message.Contains("ORA-")
这种字符串匹配方式看似简单,实则脆弱:
- Oracle 客户端语言环境不同(如中文版 Oracle),
Message里可能没有"ORA-"前缀,而是“表或视图不存在” - 某些驱动版本或连接池配置下,
Message会被截断,丢失错误码部分 - 日志脱敏策略可能自动过滤掉含
"ORA-"的日志行,导致排查断档 - 无法区分语义相近但码值不同的错误(如
1403和20000自定义异常都可能带“no data”字样)
真正稳定的信号只有 ex is OracleException && ex.ErrorCode 这一组合。只要引用的是官方 ODP.NET(Oracle.ManagedDataAccess),这个值就可靠。











