Ale*_*hov 12 oracle user-friendly
说我有列Gender和约束CHECK( Gender IN ('F', 'M', 'OTHER')).
如果我不小心忘记在客户端处理这个问题,用户会看到smth
ORA-02290: check constraint (SYS_C099871244) violated
对于用户来说也不是很有帮助,对于维护或调试的开发人员也是如此
有没有办法提供开发人员定义的消息,如(伪)Java
assert Gender IN (0,1):'Gender must be F or M'
我能想到的唯一方法是将约束移动到BEFORE UPDATE或INSERT触发器以及失败时Raise_Application_Error( code, my_message ).但我不喜欢它
编辑
具体原因的列表,如评论中所述
1.我真的希望保持逻辑尽可能接近数据
2.对于最终用户,Raise_Application_Error消息与应用程序消息
3 无法区分.即使访问数据绕过,开发人员也会看到好消息应用程序
4.将约束移动到触发器是丑陋的(是吗?),所以我必须找到与Raise_Application_Error不同的smth
EDITA2 1.5 年后,在我离开与db相关的工作之后,它终于发生在我身上,我真的不喜欢这个 - 代码重复.我必须在服务器和客户端重复完全相同的逻辑.最有可能的是,有两种不同的语言.并保持同步.这只是丑陋的.
虽然答案清楚地表明,但我无能为力.所以现在是我成为好公民并最终接受答案的时候了(对不起,只是忘记了这一点).
约束是数据库用来保护自己免受错误应用程序而不是用户的约束.
这意味着应用程序应捕获约束违规,并可能将其清除以呈现给用户.我认为一个没有这样做的申请在某种程度上是不足的.
我说'可能',因为你的申请(至少在这种情况下)应该永远不会发生这种情况.它几乎可以肯定是使用下拉限制选择控件来做类似的事情.如果它使用组合框或(震惊,恐怖)自由格式文本输入字段,则需要重新定义.
这意味着违规行为永远不会发生,除非应用程序和约束在某些时候失去同步.但是,在客户对您的应用程序进行琐碎的小动作之前很久就应该在测试中捕获这些内容.
要回答您的实际问题,Oracle中出现的用于约束违规的消息无法更改.您可以做的最好的事情是智能地命名您的约束,以便它对最终用户有意义.
但我仍然认为,向用户呈现问题是应用层的责任,而不是数据库层.
如果您正在寻找一种方法来告诉 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;
Run Code Online (Sandbox Code Playgroud)
该error_pkg.handle_exception过程将解析 Oracle 异常消息并提取约束的名称(如果它违反约束)并在交叉引用表中查找该约束名称以获取所需的消息,然后使用raise_application_error新的异常重新引发异常信息。
我想 Oracle 可以提供这样的包和表作为标准,但也许因为在实践中系统中的错误处理有许多不同的要求,所以通常认为它不够有用。