Oracle 有没有办法在违反约束时给出用户友好的错误消息

Oracle 有没有办法在违反约束时给出用户友好的错误消息,oracle,user-friendly,Oracle,User Friendly,假设我有列Gender和约束检查(性别在('F','M','OTHER')) 若我不小心忘记在客户端处理这个问题,用户将看到类似于 ORA-02290:违反了检查约束(SYS_C099871244) 这对用户和维护或调试的开发人员都不是很有帮助 有没有办法提供开发人员定义的消息,比如(伪)Java的 在(0,1)中断言性别:'Gender必须是F或M' 我能想到的唯一方法是将约束移动到更新前或插入触发器,并在出现故障时执行Raise\u Application\u Error(code,my\u

假设我有列
Gender
和约束
检查(性别在('F','M','OTHER'))

若我不小心忘记在客户端处理这个问题,用户将看到类似于
ORA-02290:违反了检查约束(SYS_C099871244)

这对用户和维护或调试的开发人员都不是很有帮助

有没有办法提供开发人员定义的消息,比如(伪)Java的
在(0,1)中断言性别:'Gender必须是F或M'

我能想到的唯一方法是将约束移动到更新前或插入触发器,并在出现故障时执行
Raise\u Application\u Error(code,my\u message)
。但是我不喜欢它

编辑 具体原因列表,如注释中所示
1.我非常喜欢让逻辑尽可能接近数据
2.对于最终用户Raise\ U应用程序\错误消息与应用程序消息无法区分
3.即使绕过应用程序访问数据,开发人员也会看到很好的消息
4.将约束移动到触发器很难看(是吗?),所以我必须找到smth不同于Raise_应用程序_错误

EDIT2 1,5年后,在我离开了与数据库相关的工作后,我终于想到了,我真正不喜欢的是-代码重复。我必须在服务器端和客户端重复完全相同的逻辑。很可能是用两种不同的语言。并保持同步。这太难看了


尽管答案清楚地表明,我对此无能为力。所以,是时候做一个好公民,最终接受一个答案了(对不起,我忘了这一点)。

约束是数据库用来保护自己不受错误应用程序的影响,而不是用户的影响

这意味着应用程序应该捕获约束冲突,并可能清理这些冲突,以便向用户演示。我会考虑一个没有这样做的应用程序在某种程度上有缺陷。

我说“可能”,因为您的应用程序(至少在这种情况下)永远不会看到这种情况发生。几乎可以肯定的是,它应该为类似的东西使用下拉式有限选择控件。如果它使用了组合框或(震惊、恐怖)自由格式文本输入字段,则需要重新定义

这意味着,除非应用程序和约束在某个点上不同步,否则冲突永远不会发生。但这是测试中应该注意的问题,早在客户接触到你的应用程序之前


为了回答您的实际问题,无法更改Oracle发出的违反约束的消息。您所能做的最好是智能地命名约束,以便最终用户能够理解它


但我仍然坚持认为,向用户展示问题是应用程序层的责任,而不是数据库层的责任。

无论约束是向客户机提出还是由支持人员登录文件进行(潜在)分析,您都应该得到一条更有用的信息

如果命名约束,它会更有用

我喜欢这样的东西

ALTER TABLE blah ADD CONSTRAINT blah_gender_ck CHECK ( Gender IN ('F', 'M', 'OTHER'));

如果您正在寻找一种方法,告诉Oracle始终将异常消息“ORA-02290:检查约束(SYS_C099871244)违犯”替换为另一条消息,如“ORA-20001:性别必须为F或M”,那么答案是:不,不能这样做

您可以做的是提供一个解决方案,供开发人员在其代码中使用,如下所示:

...
begin
    insert into emp (empno, gender) values (p_empno, p_gender);
exception
    when others then
       error_pkg.handle_exception;
end;
error\u pkg.handle\u exception
过程将解析Oracle异常消息并提取约束的名称(如果是约束冲突),并在交叉引用表中查找该约束名称以获取所需的消息,然后使用
raise\u application\u error
以新消息重新引发异常


我想Oracle可以提供这样的包和表作为标准,但可能因为在实践中系统中对错误处理有许多不同的要求,所以一般认为它不够有用。

简而言之:
据我所知,无法捕获定制处理的oracle错误。但是我认为你无论如何都不应该这么做


长版本:
然而,你的理由背后的意图是好的

我真的很喜欢让逻辑尽可能接近数据

逻辑应该尽可能接近数据,这是正确的;但是,这不符合条件-这不是逻辑,这是识别已定义逻辑异常的代码的表示,表示不应与数据或逻辑层混合(错误消息的范围覆盖了系统的每个部分;从客户端到服务器端,还要考虑翻译、一致更新、更轻松的管理和消息概述等。)

对于最终用户Raise\u应用程序,错误消息为 与应用程序无法区分 信息

是的,但反过来也是有效的,因此并不特别相关-如果您有数据库错误代码、应用程序错误代码的中央存储库,并且错误处理将对其进行处理,那么(对于最终用户)哪一层显示错误消息是不相关的。而且,从长远来看,不清楚它是否能为您节省任何工作

开发人员将看到好消息,即使绕过访问数据 应用

这是真的,对于直接访问DB的开发人员来说,会有更好的错误消息。仍然有一些注释适用于这里——在复杂系统中,不应该允许绕过应用层(即使对于开发人员也是如此);如果允许这样做,您会期望开发人员知道从哪里可以从约束名称中查找错误消息(错误代码和消息的中央存储库应/将在同一数据库中维护)

将约束移动到