最后20分求delphi开发的一个问题, 对常用delphi进行数据库开发的人来说是小菜一碟………………..我的一个输入画面,用dbgrid 作输入窗口, 我想在post前检查一下
数据是否为空﹐ 主键值是否重复, 外部键是否存在 的处理方法﹐不知各位老鸟是如何处理的
代码 ﹕
procedure Tfrm_accttype.ADOTableBeforePost(DataSet: TDataSet);
begin
  //POST 前的资料check ;
  if dataset.FieldByName('accttype').IsNull   then
  begin
      showmessage('类别代码不能为空!') ;
      abort ;
  end ;
  if dataset.FieldByName('descript').IsNull  then
  begin
      showmessage('描述不能为空') ;
      abort ;
  end;

此处如何来判定主键重复(有dsinsert 与dsedit 两种状态) 


此处如何来判定外部键重复

end;请老手们讲解一下你们常用的方法﹐或贴上一部分代码最好。。end.

解决方案 »

  1.   

    键的约束是应该留给DBMS去处理的,没有必要在客户端去处理.
    不知道你用什么数据库,
    有主键唯一约束后,重复值导致异常,就结束插入了
      

  2.   

    是否违反了约束,是由DBMS决定的,POST之前不可能客户端程序不可能知道。
    你可以用TRY EXCEPTTRY
      ADOTABLE1.POST
    EXCEPT 
      ON e:exception do showmessage(e.message) 
    end;
      

  3.   

    回复楼上﹕
    L因我用dbgrid 作输入画面. 有一些隐含post (如在插入状态上﹐改变行焦点等 )﹐
    而不是只有按<存储>才会post ﹐故 ﹐如果try except 不能全防住 .。请各提供一些建义啊…………
      

  4.   

    给你一个函数.根据函数返回值是否为空来判断就可以了function checkFieldIsNull(DataSet: TDataSet;
      FieldNames: String): String;
    var
      i: integer;
      FieldList: TStringList;   //要检查的字段列表.
      ErrorList: TStringList;   //错误信息列表
      MsgError: String;         //错误信息
    begin
      FieldList := TStringList.Create;
      ErrorList := TStringList.Create;
      //检查数据集的所有记录,从第一条记录开始检查.
      DataSet.First;
      DataSet.DisableControls;  //先置DisableControls,防止检查过程中显示数据滚动,
      try
        //注意传入的FieldNames的格式必须是 'FieldNames1,FieldNames2,FieldNames3';
        //即字段与字段之间必须是用逗号分开.
        FieldList.Delimiter := ',';
        FieldList.CommaText := FieldNames; //将字段放入列表中
        //开始检查
        for i := 0 to FieldList.Count - 1 do
        begin
          while not DataSet.Eof do
          begin
            if DataSet.FieldByName(FieldList.Strings[i]).AsString = '' then
            begin
              MsgError := Format('%s不能为空!',[DataSet.FieldByName(FieldList.Strings[i]).DisplayLabel])
              ErrorList.Add(MsgError);
            end;
            DataSet.Next;
          end;
        end;    //如果错误信息不为空则返回Result,否则Result=''
        if ErrorList.Count > 0 then
          Result := ErrorList.Text
        else
          Result := '';
      finally
        ErrorList.Free;
        FieldList.Free;
        DataSet.EnableControls; //要将数据集置为Enable
        DataSet.First;
      end;
    end;
      

  5.   

    如果你用adoquery部件连接表的话,在其onposterror事件里处理。
      

  6.   

    同意 windy2000TRY
      ADOTABLE1.POST
    EXCEPT 
      ON e:exception do showmessage(e.message) 
    end;
      
    而且你可以根据你的连接方式(如ADO,BDE等)来进一步细分Exception类,从而获得更确切的错误信息。具体可以再Delphi里按F1,看看帮助。
      

  7.   


    我想delphi中应有这样的机制﹐当系统检测到一个错误后 ﹐会引发一个错误的事件﹐我们可以在该事件中 ﹐根据不同的错误代号﹐显示不同的错误信息与处理方法回复IUPRG(遨云驰行,琢符弄图) (  
    能否给一段你在onposterror事件的代码参考一下.
      

  8.   

    是的,是有这样的机制。
    这是我以前用过的一段代码,仅供参考:
    放在onposterror里的。
    ...
    VAR imyDBlERROR:INTEGER;
    begin
        IF (E IS EDBENGINEERROR) THEN
        BEGIN
           ImyDBLERROR:=(E as eDBENGineError).Errors[0].Errorcode;
          // messagedlg('错误码:'+inttostr(idblerror),mtwarning,[mbok],0);
          // abort;       case imyDBlError of
                eRequiredFieldMissing:
                begin
                    messagedlg('请输入 名称)!',mtwarning,[mbok],0);
                    abort;
                end;
                eKeyViol:
                begin
                    messagedlg('该企业已经被输入!请重新录入!',
                               mtwarning,[mbok],0);
                    abort;
                end;
           end;
       end;
    end;