假如用的是BDE的数据库编程,在增加、删除、修改向数据库提交时可能发生类似于关键字不能重复、不能为空等错误, 我怎么通过Delphi自带的错误E(E: EDatabaseError)来提取错误代码,或者有哪些更好的方法知道错误是属于哪钟类型,现在我只能通过E.Message显示错误信息,但这样我觉得不好,没有经过处理,人家可能看不明白!谢谢!

解决方案 »

  1.   

    李维有一本书叫ADO_MTS_COM+高级数据库编程的,里面好像谈到这个类似的问题,虽然是ADO的技术,我推荐你去参考一下。
      

  2.   

    BDE 都是古董了,用ADO 把
      

  3.   

    笨方法就是在POST之前定义你预见的错误,如主键重复,不能为空等,从而判断。
      

  4.   

    但是有写错误是Sql Server 提供的。
    我觉得还是在保存之前自己判断错误比较好
      

  5.   

    大家说的都很好,我自己用的也是ADO,在此我不谈论ADO与BDE谁更好!
    如果判断关键字是否重复在提交之前判断是不科学的:
    1、要查询一次,浪费很多时间
    2、即使保证查询是不重复,在查询之后其他人同时提交了此数据。
    另有的错误是在删除之前可能难以预测的,如外键问题,可能某个表的字段是其他几十个表的外键,难道都得要查询一次。
    所以大家不要觉得问题简单,能否更好的解决是我们要谈的。
      

  6.   

    try
    ...
    except
    on Er:exception do
    if Er is EDBEngineError then
     begin
       ErCode:=EDBEngineError(Er).Errors[0].ErrorCode;
       case ErCode of
         ...
        else
         ...
        end;
       ...
      end;
    ...
    //raise; 可重新引发异常,让全局异常处理子程序来进行处理。
    ...
    end;
      

  7.   

    cosmart(CoolSmart) 的答案好象不是很符合!
    例如E: EDatabaseError此时E is not EDBEngineError  kenmaj() 可以谈谈你的想法,系统自己提示的那些信息(关键字、外键等信息),如何识别,以更好的转化为更容易理解的提示!
      

  8.   

    try
    ...
    except
    on Er:exception do
    if Er is EDBEngineError then
     begin
       ErCode:=EDBEngineError(Er).Errors[0].ErrorCode;
       case ErCode of
         ...
        else
         ...
        end;
       ...
      end;
    ...
    //raise; 可重新引发异常,让全局异常处理子程序来进行处理。
    ...
    end;
    中的EDBEngineError如果用的BDE连接才用,如果用的是ADO就没有用了!
    ADO又改该如何
      

  9.   

    只要你用BDE操作数据库, EDBEngineError包括了全部的错误了。
      

  10.   

    cosmart(CoolSmart)的办法可以实现,但个人觉得不是好办法:
    需要将exception派生类的顺序从上到下依次if判断
    使用过多的if已经够xx了,还要要求顺序!不知道你的意思是什么,如果只是要求格式化出错消息的话,你可以
    1 重新编译delphi的出错信息单元,用中文的代替
    2 自己建一张出错代码和信息的对应表,使用数据驱动的方式如果要根据不同的错误采取不同的action,就比较麻烦,关键看你的action是什么。这种情况建议使用except的继承以及虚函数调用的模式。而不是switch...
      

  11.   

    ps,ado也有exception的类,自己看ado的unit吧
      

  12.   

    谢谢以上各位的意见,其实我主要目的是:
    在向数据库提交时(任何数据库),假如发生关键字不能重复错误,如果直接显示E.Message信息,用户可能看不明白,我就想把他翻译一下(如提示为关键字重复),就是如何判别那种错误是属于关键字不能重复??
      

  13.   

    ADO是用OLE的
    那就用
    ...
    try
    ...
    except
    on ex:exception do
    if ex is EOleException then
     msg:=EOleException(ex).Message
    //iCode:=EOleException(ex).ErroCode;
    ...
     end;
    ...
    end;
    ...
      

  14.   

    cosmart(CoolSmart):
    iCode:=EOleException(ex).ErroCode;
    产生的提示代码有问题:
    我测试了两种不同的错误而出现的提示代码则是一样的?
    不知你出现过这个问题??
      

  15.   

    没有试过,但你可以用message来判断,
    要实现你提出的问题其实也不难啊。
    比如你测试关键字重复的时候,会触发一个异常,并把message显示出来
    然后在异常里判断决定显示你制定的消息
    假如提示message='your input value has been in identify field';
    if E.message='your input value has been in identify field' then
    showmesage('你输入的关键字重复,请重新输入');同时也可以避免以上重复显示给客户,设置自动增量字段
    SQL Server实现:
    CREATE TABLE Products
    (user_id INT(16)AUTO_INCREMENT,user_name VARCHAR(10),  UNIQUE (`user_id`));
    Access实现就不用说了,在设计的时候有自动填充的选项。另外也可以通过编程实现,比如对于提货单编号,这一般都是日期+编号的,让数据库自动填充是无法得到想要的编号的,这时自己编程实现。
    关键看采用什么的算法适合你。
    对于出现同一个提示代码,可能是你这2种测试都是属于一种的错误,才会触发同样的提示代码。