在delphi中,利用ADO对SQL Server 进行操作的时候,往往会产生一些错误,在DELPHI里则表现为异常。例如:当我们往SQL Server里面插入一个具有唯一性约束的重复记录值,SQL Server则会引发编号为2627的错误:违反了 %1! 约束 ''%2!''。不能在对象 ''%4!'' 中插入重复键。在delphi里设计程序时,难免要做这样的异常处理。
下面是做的一个测试程序:
一个ADOConnection1,一个ADOCOmmand1,一个ListBox1用于显示错误信息:
ADOConnection1连接到SQL Server的数据库,
ADOCommand1使用ADOConnection1作为数据连接,
ADOCommand1.commandText:='insert into MyTable (stID,Score)values(2,54)';
//其中stID具有唯一性约束,如果数据库中已经存在stID=2的记录,则以上命令执行后将会产生一个2627的错误即异常,我们可以这样处理这个异常:
try
ADOCommand1.Execute;
except
//ADOCommand1.Connection等效于ADOConnection1,因为我做测试的时候是在一个函数里测试整个过程的,该函数并没有
//直接引用ADOConnection1,当然也可以直接用ADOConnection1,完全是个人习惯问题
ListBox1.Items.Add(IntToStr(ADOCommand1.Connection.Errors.Count));//取得产生的错误总数,在Errors集合中
for I:=0 to ADOCommand1.Connection.Errors.Count-1 do //准备取出产生的所有错误
begin
ListBox1.Items.Add(IntToStr(ADOCommand1.Connection.Errors[k].Number));//错误代码,这是Delphi转换过的代码?
ListBox1.Items.Add(ADOCommand1.Connection.Errors[k].Source);//产生错误的源
//产生错误的原生代码,即SQL Server的代码,在我们的例子中你将看到显示的是2627,因此这个代码才是我们真正需要的
ListBox1.Items.Add(IntToStr(ADOCommand1.Connection.Errors[k].NativeNumber));
end;
记得李维的《Delphi 5.X ADO_MTS_COM+高级程序设计篇》里好像讲到为什么会有Delphi转换过的代码和原生代码共存的问题,大约是DELPHI想封装所有的错误包括那些没有包含在SQL Server里的错误。
我们可以看ADOConnection里的属性,其中一个属性就是对Errors的封装:
Error=ADOInt.Error
Errors =ADOInt.Errors;
在ADOInt中对Error和Errors的定义:
Error = interface(IDispatch)
['{00000500-0000-0010-8000-00AA006D2EA4}']
function Get_Number: Integer; safecall;
function Get_Source: WideString; safecall;
function Get_Description: WideString; safecall;
function Get_HelpFile: WideString; safecall;
function Get_HelpContext: Integer; safecall;
function Get_SQLState: WideString; safecall;
function Get_NativeError: Integer; safecall;
property Number: Integer read Get_Number; //该属性返回错误代码
property Source: WideString read Get_Source; //返回产生错误的源
property Description: WideString read Get_Description;
property HelpFile: WideString read Get_HelpFile;
property HelpContext: Integer read Get_HelpContext;
property SQLState: WideString read Get_SQLState;
property NativeError: Integer read Get_NativeError;//返回产生错误的原生错误代码,即SQL Server的错误代码
end;
//对Errors的定义,其中Item[Index:Olevariant]的属性被定义成Default,因此可以用Errors[I]来访问,返回的对象是Error对象
Errors = interface(_Collection)
['{00000501-0000-0010-8000-00AA006D2EA4}']
function Get_Item(Index: OleVariant): Error; safecall;
procedure Clear; safecall;
property Item[Index: OleVariant]: Error read Get_Item; default;
end;