关于数据库错误处理的简单问题(80分)

  • 主题发起人 主题发起人 Laputa
  • 开始时间 开始时间
L

Laputa

Unregistered / Unconfirmed
GUEST, unregistred user!
用户在DBGrid上输入出错(如非空字段为空,日期字段输入无效值等)时会跳出系统提示,怎样截获
系统提示判断错误类型并用用自己的提示代替?
书上说在OnPostError中处理,可我试了试出错时根本不执行OnPostError过程:
设表里有两个字段a,b,B为非空字段,
procedure TForm1.Table1PostError(DataSet: TDataSet; E: EDatabaseError;
var Action: TDataAction);
begin
if (E as EDBEngineError).Errors[0].Errorcode=9732 then
begin
showmessage('B为非空字段');
Abort;
end;
end;
在DBGrid上填入a,提交,却直接跳出系统提示"field 'b' must have a value",单步跟踪
发现根本不运行OnPostError过程。请问该怎么办?
 
可以在DataSource的OnUpdateData事件中写代码,如:
procedure TForm1.DataSource1UpdateData(Sender: TObject);
begin
if DataSource1.DataSet.FieldByName('x').asstring='' then
begin
ShowMessage('x值不能为空');
DataSource1.DataSet.Cancel;
end;
....
end;
 
to yaan:
我试过了,似乎不行。一执行table1.append马上会触发Datasource的OnUpdateData事件,此时Table1
的当前记录是刚加入的空记录,所有数据均尚未输入,OnUpdateData的代码检查都是徒劳的
 
OnUpdateData事件是在提交数据的时候才会触发,Append只是插入记录,并没有提交,应该不会触发OnUpdateData的。
 
我的办法有三,
一、直接修改DBGrid.pas文件,因为设计直接修改了VCL,所以不推荐使用。
二、使用Query的OnSetText事件,在这里面判断,如果不符合要求,就直接执行Abort退出
这样就可以了。但是,如果存在很多这样的东西,工作过于繁琐。
三、不使用DBGrid进行数据输入,尽量使用自己的Edit等,而避免DBEdit等,但是……

唉,我就这些办法了,但是自己总感觉都不好。
再听听别人的办法。
 
1。gz
2。绑定后在DBGRID中输入数据总有出现意想不倒的情况
 

yaan,很对不起,又试了一下,OnUpdateData确实是post时才判断的。不知道刚才怎么试的,
不是我的机子疯了就是我疯了:(
可是还有一个问题:OnUpdateData没有返回EDatabaseError参数。
处理简单的表确实可以在OnupdateDate检查,可如果字段复杂,可能的错误很多:非空字段
为空,关键字重复,字段类型不匹配,加上主从表关联可能的错误等等,如果表中牵涉到
大量字段,用代码判断是很大的工作量。
有没有一个过程能截取数据库返回的EDatabaseError类型,让我们能用一个Case语句判断
错误类型,并截取,给出自己的提示?这样就不用挨个字段检查了。原本OnPostError正合用,
可为什么不执行?是不是DBGrid的错误检测抢在了table前面?可我在DBGrid中又找不到类似
Table的OnPostError的过程
各位以前执行数据录入时是怎么处理这个问题的?还是都不用dbgrid而另外开窗口用DBedit
逐条添加逐条判断?
盼高手指点,多谢!:)
 
当然有!你的意思是想把那些英文出错提示全部提示为中文吧,捕获系统级
Application.OnException即可!给你关键的代码(都在主form里写即可)
public
procedure myExceptHandle(Sender : TObject; E : Exception);
.......
procedure TMainForm.myExceptHandle(Sender : TObject; E : Exception);
begin
if Pos('valid date',E.Message) > 0 then
Application.messagebox(' 日期非法!',pchar(application.title),mb_iconstop+mb_ok)
else if Pos('Value out of bounds',E.Message) > 0 then
Application.messagebox(' 数据超出范围!',pchar(application.title),mb_iconstop+mb_ok)
else if Pos('a valid floating point',E.Message) > 0 then
Application.messagebox(' 无效的数值!',pchar(application.title),mb_iconstop+mb_ok)
else
application.showexception(e);
end;
并在你的主form的create事件中写
Application.OnException := myExceptHandle;



 
你直接在TField的OnValidate做不行吗?
 
挨个字段写OnValidate有些麻烦,我比较懒 :P
呵,SoftBoy前辈的办法好,价格便宜量又足,就是它了:)
多嘴再问一句,OnPostError事件什么时候触发?只是摆设?!
 
存盘出错时触发啊,也就是说Post过程出错时触发
 
OnPostError是试图修改或插入记录时出错而触发的;具体细节参看Delphi帮助。
 
看过好几遍帮助了,所以才奇怪。理论上是该Post出错时触发的,可出错时就是不运行。
用个最简单的例子:
Table1里有两个字段:a,b,其中b为非空字段
BtAdd按钮:
Table1.Append;
BtPost按钮:
Table1.Post;
TForm1.Table1PostError过程:
showmessage('A Beautiful Day');
点BtAdd,再点BtPost,由于B为非空字段,出错,跳出field 'b' must have a value的系统提示,
原该执行的TForm1.Table1PostError却躺在床上动也不动,怎么会这样?
 
为什么不在,程序的外面捕捉,通过它的错误号来判断
根据Delphi的异常处理机制,下一层没有处理的异常会自动转到上一层
 
不可能吧,我用Ado试过了,没问题啊,都是先到Posterror的,你再仔细看看
 

用ADO试了一下,可以触发OnPostError,但要是用ODBC,试过无数遍了,确实不执OnPostError。
我用的是Delphi5,SQL7,Win2000。是我的机器问题,还是Borland的Bug?

To reysky:
Delphi的异常处理机制我不太懂,能说得详细些吗,怎样在程序的外面捕捉,通过操作什么对象
来判断错误号及做出相应处理?
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部