【问题标题】:Trap key violation陷阱密钥违规
【发布时间】:2012-04-15 20:28:10
【问题描述】:

您好,我正在尝试进行一些异常处理并拦截重复的字段值(键违规)错误。在我寻找解决方案的过程中,我看到了许多使用

来捕获所有错误的建议
try
(enter code)
except on E: EDatabaseError do
showmessage (Error message);
end; 

但我想专门响应密钥违规,它使用使用 ADO 的访问表。

【问题讨论】:

  • 什么具体标识了您希望捕获的异常?
  • 当我使用已经存在的客户端 ID(主键)向我的系统添加新客户端并返回以下消息时, - 引发异常类 EOleException 并带有消息“您请求的更改表不成功,因为它们会在索引、主键或关系中创建重复值'
  • 那么如果我再次运行,将返回相同的消息,但使用 EDatabaseError 而不是 EOleException
  • 是的,但在错误消息中我希望能够声明输入的客户端 ID 已经存在,并且使用一般异常可能会捕获与客户端 ID 无关的其他各种错误,这些错误肯定已经存在跨度>
  • 看看例如在this article.

标签: delphi delphi-7 ado


【解决方案1】:

如果您要处理的唯一错误是带有“重复值”消息的错误,这将起作用:

try
  // Your code
except
  on E: EOleException do
  begin
    // The better way is to find out what E.ErrorCode is
    // for this specific exception, and handle it instead
    // of checking the string - you didn't provide the
    // ErrorCode, though.
    // If E.ErrorCode = <whatever> then
    //
    if Pos('duplicate value', E.Message) > 0 then
      // You've got a duplicate with the message above
      // Do whatever handles it
    else
      raise;
  end;
  // If you want to handle other exception types (eg., EDataBaseError),
  // you can do so here:
  //  on E: EDataBaseError do
  //    HandleDBError;
end;

【讨论】:

  • 本地化是否可能导致在非英语系统上失败?只是一个想法!此外,您的代码会吞下所有 EOleException 异常。
  • 刚刚更新了我的答案以提供一个没有这个问题的更好的解决方案。请参阅Pos 行上方的 cmets。 :)
  • @user 使用调试器或日志记录
  • @user1277240,只是导致异常发生,并在异常代码中执行ShowMessage(Format('ErrorCode: %d', ]E.ErrorCode]));以获取ErrorCode;它总是一样的,如果语言发生变化,消息可能会发生变化(正如大卫指出的那样)。
  • @David,感谢您收看我上次修订时错过的else raise。我以为我已经添加了它,只是注意到我没有,当我进入编辑时它就在那里。以为我快疯了,直到我回去刷新问题页面并看到您的编辑。 :)
【解决方案2】:

EDatabaseError 只是一个通用的 excption 类,没有关于错误的附加信息,要在 ADO 中获取有关错误的扩展信息,您必须使用 TADOConnection.Errors 属性来获取 Key violation 异常时的特定错误代码引发,为此检查 NumberNativeError 属性。

您可以在此处找到有关此主题的更多文档

【讨论】:

    【解决方案3】:

    根据您的描述,这听起来不像是例外情况。特别是如果你只需要继续EOleException。例外情况应该是您没有很好的处理方式的事情,而这里不是这种情况。

    我建议您在尝试添加新记录之前检查新 ID 是否已被使用。或者,正如@TLama 建议的那样,利用数据库框架的任何错误处理工具,让您在它变成异常之前挂钩它。

    【讨论】:

    • @ken 交易处理 2 并且您有关于 1 的观点。也许性能问题太大了。我是从编程方面而不是从数据库的角度考虑的。
    • 但这很可能在某些数据库数据服务控制事件中捕获
    • @TLama,它在哪里被抓住并不重要。它仍然必须被抓住。
    • @Ken,我说的是正确的 ADO 控制错误处理,而不是 按下按钮并等待我遇到异常 ;-) 例如TClientDataset 错误可能会以 this 的方式处理。
    • @TLama,对我来说听起来是个好地方(如果发布者使用的是TADOQuery)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    相关资源
    最近更新 更多