d7+ado+access ,我在数据库里把一个表的某个字段设置了数据库有效性规则,>0,程序在s运行时如果我输入了违反有效性规则的数字,则会弹出一个对话框,说''table1.column1'设置的有效性规则‘>0'禁止一个或多个数值,请输入一个该字段可以接受的数值'',我的问题是,我该怎么在程序里捕捉这个用户输入错误,然后将这个默认对话框屏蔽掉,弹出自己的自定义对话框,这样会显得比较友好,用户也更容易理解! 类似的情况还有,我设置了某个字段为主键,而用户输入了不是唯一值,同样会报错,我该怎么自定义提示对话框!!!!!
我想在数据库里尽可能把业务规则制定好,这样也许会省却一些程序代码,我也知道也可以在程序里编写代码来捕捉错误,但这样似乎不地道,欢迎您的评论!!!!
急急急,希望高手不吝赐教!!!!!!!!!!!!!!!!!
我想在数据库里尽可能把业务规则制定好,这样也许会省却一些程序代码,我也知道也可以在程序里编写代码来捕捉错误,但这样似乎不地道,欢迎您的评论!!!!
急急急,希望高手不吝赐教!!!!!!!!!!!!!!!!!
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;
这我可以理解,那 我设置了某个字段为主键,而用户输入了不是唯一值,同样会报错,我该怎么自定义提示对话框!!!!!
该怎么办????????????????
用BDE的方法
在ADO 上好象不行的啊
学习!!
在ADODataSet的OnPostError事件里写上
action := daabort;
application.MessageBox('保存出错!!','提示',0);
ADODataSet.Cancel();
可是这样的话就会将各种错误归为同一种提示,,怎么将不同的错误细分呢,如何辨别是违反了<0的有效性规则还是违反了主键重复输入的原则,再根据不同的错误作出不同的提示???
都会抛出一个异常(这可以在调试的时候看到这个异常类名)
然后你用try捕捉处理这个异常,这样试试看行不行
============================================
来自: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;
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.
用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这边怎样做才能替换数据库的错误提示呢?