d7+ado+access ,我在数据库里把一个表的某个字段设置了数据库有效性规则,>0,程序在s运行时如果我输入了违反有效性规则的数字,则会弹出一个对话框,说''table1.column1'设置的有效性规则‘>0'禁止一个或多个数值,请输入一个该字段可以接受的数值'',我的问题是,我该怎么在程序里捕捉这个用户输入错误,然后将这个默认对话框屏蔽掉,弹出自己的自定义对话框,这样会显得比较友好,用户也更容易理解!  类似的情况还有,我设置了某个字段为主键,而用户输入了不是唯一值,同样会报错,我该怎么自定义提示对话框!!!!!
  
  我想在数据库里尽可能把业务规则制定好,这样也许会省却一些程序代码,我也知道也可以在程序里编写代码来捕捉错误,但这样似乎不地道,欢迎您的评论!!!!
急急急,希望高手不吝赐教!!!!!!!!!!!!!!!!!

解决方案 »

  1.   

    在那个字段的SetText里面写上你的屏蔽错误的代码?
      

  2.   

    每个数据库字段都有一个OnSetText事件
    procedure TForm1.ADOTable1DSDesignerSetText(Sender: TField;
      const Text: String);
    begin
        try
            strtoint(Text);
        except
            ShowMessage('请输入整数');
        end;
        if strtoint(Text)<=0 then
        begin
            ShowMessage('请输入大于零的整数');
            exit;
        end;
    end;
      

  3.   

    to  qixin000(小齐) 
      这我可以理解,那 我设置了某个字段为主键,而用户输入了不是唯一值,同样会报错,我该怎么自定义提示对话框!!!!! 
       该怎么办????????????????
      

  4.   

    help help help helphelp helphelp helphelp helphelp helphelp helphelp helphelp helphelp helphelp helphelp helphelp helphelp helphelp helphelp helphelp help
      

  5.   

    对啊
    用BDE的方法
    在ADO 上好象不行的啊
    学习!!
      

  6.   

    你只定义了有效性规则,在ACCESS中,定义完有效性规则,还可以定义“有效性文本”,就在有效性规格的下面,等你输入一个无效的值后,就会显示出含有“有效性文本”的对话框了。
      

  7.   

    to moonwzy(令狐不冲)
    在ADODataSet的OnPostError事件里写上
    action := daabort;
    application.MessageBox('保存出错!!','提示',0);
    ADODataSet.Cancel();
      

  8.   

    to  qixin000(小齐) 
      可是这样的话就会将各种错误归为同一种提示,,怎么将不同的错误细分呢,如何辨别是违反了<0的有效性规则还是违反了主键重复输入的原则,再根据不同的错误作出不同的提示???
      

  9.   

    输入重复值或违反有效性的时候
    都会抛出一个异常(这可以在调试的时候看到这个异常类名)
    然后你用try捕捉处理这个异常,这样试试看行不行
      

  10.   

    转贴别人的,希望对你有帮助:
    ============================================
    来自:zhangkan 时间:2001-11-5 18:19:00 ID:708586 你可以自己定义一个错误类,然后将Application.OnException指向它,下面是一个简单的例子.
    这样,程序中的任何错误都逃不过它,你就可以将数据库及其它相关的错识代码写在里面,出
    了什么问题,根据错误代码来提示,就不用你每个地方来写错误出错了.unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,unit3;type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;  procedure AppException(Sender: TObject; E: Exception);var
      Form1: TForm1;
      MyExceptionHandle:TMyExceptionHandle;implementationuses Unit2;{$R *.dfm}procedure AppException(Sender: TObject; E: Exception);
    begin
      if pos('valid integer',e.Message)>0 then
         ShowMessage('OK')
      else
         Application.ShowException(E);
    end;procedure TForm1.Button1Click(Sender: TObject);
    var aa:string;
        ii:integer;
    begin
      aa:='b';
      ii:=strtoint(aa);
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      MyExceptionHandle:=TMyExceptionHandle.Create;
      Application.OnException := MyExceptionHandle.AppExeption;
    end;end. 
    来自:pine_ant 时间:2001-11-6 13:27:00 ID:710377 to YNTW
      象主键冲突这种错误在这里面没有啊,另外我觉得这些肯定应该是数据库返回的
    错误信息,这些错误的错误码和错误描述在delphi中有可能没有(我没有找到,:))
    从报的错误来看,是EOleException类型的.希望进一步探讨to zhangkan
      你所说的工作直接在Application.OnException中定义就是了,不必再写函数也可以吧. 
    来自:zhangkan 时间:2001-11-6 13:47:00 ID:710428 to pine_ant,你就写在下面就行了,我不是有一个例子吗?
    procedure AppException(Sender: TObject; E: Exception);
    begin
      if pos('valid integer',e.Message)>0 then//这儿就是出错信息,假如你是数据库方面的
    错误,你就可根据这个信息来确定是什么错误.实际上我更偏向于建一个错误表,将这些错误
    信息放在里面,这样也好扩充,你这儿也不需要写多少,编译好后也不必再改这儿.就看你是放
    在数据库中还是另外一个数据文件中.
         ShowMessage('OK')
      else
         Application.ShowException(E);
    end;
     
      

  11.   

    来自:YNTW 时间:2001-11-7 13:17:00 ID:708557 产生错误后从Errors中取得错误:
      ADOConnection.Errors.Item[1].Get_Number//取得错误号
      ADOConnection.Errors.Item[1].Get_Description//取得描述信息
      .......不好意思,记错文件名了,大概你要的是这些吧?
    {*******************************************************}
    {                                                       }
    {       Borland Delphi Visual Component Library         }
    {                                                       }
    {       Copyright (c) 1997,99 Inprise Corporation       }
    {                                                       }
    {*******************************************************}unit DbConsts;interfaceresourcestring
      SInvalidFieldSize = '字段大小无效';
      SInvalidFieldKind = '字段类型无效';
      SInvalidFieldRegistration = '字段注册无效';
      SUnknownFieldType = '字段 ''%s'' 类型未知';
      SFieldNameMissing = '字段名丢失';
      SDuplicateFieldName = '字段名 ''%s'' 重复';
      SFieldNotFound = '未发现字段 ''%s''';
      SFieldAccessError = '无法将字段 ''%s'' 作为 %s 类型存取';
      SFieldValueError = '字段 ''%s'' 取值无效';
      SFieldRangeError = '%g 对于字段 ''%s'' 是无效的. 允许的取值范围是从 %g 到 %g';
      SInvalidIntegerValue = '''%s'' 对于字段 ''%s'' 不是有效的整数值';
      SInvalidBoolValue = '''%s'' 对于字段 ''%s'' 不是有效的布尔值';
      SInvalidFloatValue = '''%s'' 对于字段 ''%s'' 不是有效的浮点值';
      SFieldTypeMismatch = '字段 ''%s'' 类型不匹配, 希望类型: %s, 实际类型: %s';
      SFieldSizeMismatch = '字段 ''%s'' 大小不匹配, 希望大小: %d, 实际大小: %d';
      SInvalidVarByteArray = '字段 ''%s'' 变量类型或大小无效';
      SFieldOutOfRange = '字段 ''%s'' 取值超界';
      SBCDOverflow = '(溢出)';
      SFieldRequired = '字段 ''%s'' 必须赋值';
      SDataSetMissing = '字段 ''%s'' 没有指定数据集';
      SInvalidCalcType = '字段 ''%s'' 不能作为计算字段或查找字段';
      SFieldReadOnly = '字段 ''%s'' 不能修改';
      SFieldIndexError = '字段索引超界';
      SNoFieldIndexes = '目前没有活动的索引';
      SNotIndexField = '字段 ''%s'' 没有索引, 无法修改';
      SIndexFieldMissing = '无法存取索引字段 ''%s''';
      SDuplicateIndexName = '索引名重复 ''%s''';
      SNoIndexForFields = '字段 ''%s'' 没有索引';
      SIndexNotFound = '未发现索引 ''%s''';
      SDuplicateName = '%s 中 ''%s'' 重名';
      SCircularDataLink = '不允许循环的数据连接';
      SLookupInfoError = '字段 ''%s'' 的查找信息不完整';
      SDataSourceChange = '数据源不能修改';
      SNoNestedMasterSource = '嵌套的数据集不能拥有主数据源';
      SDataSetOpen = '无法在打开的数据集上执行该操作';
      SNotEditing = '数据集不在修改或插入模式';
      SDataSetClosed = '无法在关闭的数据集上执行该操作';
      SDataSetEmpty = '无法在空数据集上执行该操作';
      SDataSetReadOnly = '无法修改只读的数据集';
      SNestedDataSetClass = '嵌套的数据集必须从 %s 继承';
      SExprTermination = '过滤表达式不正常结束';
      SExprNameError = '字段名未终止';
      SExprStringError = '字符串常数未终止';
      SExprInvalidChar = '无效的过滤表达式字符: ''%s''';
      SExprNoLParen = '希望 ''('', 但发现了 %s';
      SExprNoRParen = '希望 '')'', 但发现了 %s';
      SExprNoRParenOrComma = '希望 '')'' 或 '','', 但发现了 %s';
      SExprExpected = '希望表达式, 但发现了 %s';
      SExprBadField = '字段 ''%s'' 不允许在过滤表达式中使用';
      SExprBadNullTest = 'NULL 只允许用于 ''='' 和 ''<>''';
      SExprRangeError = '常数超界';
      SExprNotBoolean = '字段 ''%s'' 不是布尔类型';
      SExprIncorrect = '过滤表达式形式不正确';
      SExprNothing = '无';
      SExprTypeMis = '表达式类型不匹配';
      SExprBadScope = '该操作不能混合合计值和各记录变化的值';
      SExprNoArith = '不支持过滤表达式中的算法';
      SExprNotAgg = '表达式不是合计表达式';
      SExprBadConst = '常数不是正确的 %s 类型';
      SExprNoAggFilter = '过滤中不允许合计表达式';
      SExprEmptyInList = 'IN 列表不能为空';
      SInvalidKeywordUse = '关键字使用错误';
      STextFalse = '假';
      STextTrue = '真';
      SParameterNotFound = '未发现参数 ''%s''';
      SInvalidVersion = '无法载入约束参数';
      SParamTooBig = '参数 ''%s'', 无法保存大于 %d 字节的数据';
      SBadFieldType = '不支持字段 ''%s'' 的数据类型';
      SAggActive = '合计处于活动状态时不能修改属性';
      SProviderSQLNotSupported = 'SQL 不支持: %s';
      SProviderExecuteNotSupported = '运行不支持: %s';
      SExprNoAggOnCalcs = '字段 ''%s'' 的类型不能用于汇总计算, 使用内部计算';
      SRecordChanged = '记录已由其他用户修改';
      
      { DBCtrls }
      SFirstRecord = '第一条记录';
      SPriorRecord = '前一条记录';
      SNextRecord = '下一条记录';
      SLastRecord = '最后一条记录';
      SInsertRecord = '插入记录';
      SDeleteRecord = '删除记录';
      SEditRecord = '修改记录';
      SPostEdit = '保存改动';
      SCancelEdit = '取消改动';
      SRefreshRecord = '刷新数据';
      SDeleteRecordQuestion = '删除记录吗?';
      SDeleteMultipleRecordsQuestion = '删除所有选中的记录吗?';
      SRecordNotFound = '未发现记录';
      SDataSourceFixed = '操作不允许在 DBCtrlGrid 上执行';
      SNotReplicatable = '控件不允许在 DBCtrlGrid 中使用';
      SPropDefByLookup = '属性已由查找字段定义了';
      STooManyColumns = '表格试图显示超过256列';  { DBLogDlg }
      SRemoteLogin = '远程登录';  { DBOleEdt }
      SDataBindings = '数据绑定...';implementationend.
    {*******************************************************}
    {                                                       }
    {       Borland Delphi Visual Component Library         }
    {                                                       }
    {       Copyright (c) 1999 Inprise Corporation          }
    {                                                       }
    {*******************************************************}unit ADOConst;interfaceresourcestring
      SInvalidEnumValue = 'Invalid Enum Value';
      SMissingConnection = 'Missing Connection or ConnectionString';
      SNoDetailFilter = 'Filter property cannot be used for detail tables';
      SBooksRequired = 'Dataset does not support books, which are required for multi-record data controls'; 
      SMissingCommandText = 'Missing %s property';
      SNoResultSet = 'CommandText does not return a result set';
      SADOCreateError = 'Error creating object.  Please verify that the Microsoft Data Access Components 2.1 (or later) have been properly installed';
      SEventsNotSupported = 'Events are not supported with server side TableDirect cursors';
      SUsupportedFieldType = 'Unsupported field type (%s) in field %s';
      SNoMatchingADOType = 'No matching ADO data type for %s';
      SConnectionRequired = 'A connection component is required for async ExecuteOptions';
      SCantRequery = 'Cannot perform a requery after connection has changed';
      SNoFilterOptions = 'FilterOptions are not supported';implementationend. 
      

  12.   

    怎样处理数据库的异常
        用Delphi开发数据库系统时,一定会遇到与数据库配合的问题,最基本的一个问题就是怎样处理数据库约束(constraint)产生的错误。如果用户录入的数据违反约束,数据库会产生类似“Violation of PRIMARY KEY constraint ’PK__table1__07F6335A’. Cannot insert duplicate key in object ’table1’. The statement has been terminated.”这样含混的提示,而用户真正希望看到的是“商品已经存在,您输入的编号重复,请重新输入。”这样的提示,怎样才能把数据库的异常转换为用户可以理解的错误提示呢?这是一个非常常见的问题,但令人遗憾的是在用户手册和流行的参考资料中都找不到直接答案,所以很多开发人员使用了一些令人哭笑不得的办法。比如不创建主键(primary key),而是在每次插入数据之前先查询是否存在相同的数据。又比如不创建外键(foreign key),靠额外的查询来检查数据是否冲突。姑且不论这样做程序代码会有多么臃肿,仅从理论上就可以推论出这是违反并发控制原理的,在你查询和插入之间其它用户完全可能改变了数据库,也就是说用提前查询的办法来代替约束只解决99%的问题,而且随着并发用户的增加,这个百分比还会下降。因此,并发情况下只能依靠数据库约束检查数据,那么Delphi这边怎样做才能替换数据库的错误提示呢?