这段代码出了什么问题?

时间:2011-07-27 03:18:59

标签: delphi

在这种情况下,我有一些代码在现有程序中没有问题,但是当我在新程序中使用它时会抛出异常。

它可能不是最好的代码,但它每天都在使用......

Function  DoSQlCommandWithResultSet(const command : String; 
                                    AdoConnection : TADOConnection; 
                                    resultSet : TStringList): Boolean;
  var i : Integer;
      AdoQuery : TADOQuery;
begin
  Result := True;
  resultSet.Clear();

  AdoQuery := TADOQuery.Create(nil);
  try
    AdoQuery.Connection := AdoConnection;
    AdoQuery.SQL.Add(command);
    AdoQuery.Open();

    i := 0;
    while not AdoQuery.eof do
    begin
      resultSet.Add(ADOQuery.Fields[i].Value);
      AdoQuery.Next;
      Inc(i);
    end;

  finally
    AdoQuery.Free();
  end;
end;

是的,它可能需要一个try / catch并且不使用布尔结果,但它可以工作......

....在之前的程序中,但在新的程序中,它在调用时发出异常......

procedure TForm1.FormCreate(Sender: TObject);
   var my_stringlist : TStringList;
       i : integer;
begin
   AdoConnection := TADOConnection.Create(nil);

   if ConnectToDefaultDatabase(AdoConnection) = False then
      MessageDlg('Agh !', mtError, [mbOK], 0);

   my_stringlist := TStringList.Create();
   if DoSQlCommandWithResultSet('show databases', AdoConnection, my_stringlist) = False then
      MessageDlg('Urk !', mtError, [mbOK], 0);

   for i := 0 to Pred(my_stringlist.Count) do
      memo1.Lines.Add(my_stringlist.Strings[i]);
end;  // FormCreate()

现在,这是有趣的部分......它会在Inc(i)上引发异常,如果我用for循环替换while循环...

    for i := 0 to Pred(ADOQuery.Fields.count) do
      resultSet.Add(ADOQuery.Fields[i].Value);

它运作得很好。

我想我可以使用for循环&继续前进,但我想了解出了什么问题......有人可以向我解释一下吗?感谢

2 个答案:

答案 0 :(得分:6)

首先突然出现的是

i := 0;
while not AdoQuery.eof do
begin
  resultSet.Add(ADOQuery.Fields[i].Value);
  AdoQuery.Next;
  Inc(i);
end;

for i := 0 to Pred(ADOQuery.Fields.count) do
  resultSet.Add(ADOQuery.Fields[i].Value);

在语义上等效!当您致电Next时,您正在推进数据集中的当前记录。直到您点击EOF为止的循环将遍历数据集中的每条记录一次。但是第二个循环从不调用Next并且不检查EOF;它抓住了一条记录中的所有字段。

如果我不得不猜测第一个循环中导致异常的原因,我会说你的数据集中的记录(行)比字段(列)多,所以经过足够的迭代后,{{1} }结束于i,你得到一个超出范围的索引错误。

你到底想做什么?

答案 1 :(得分:4)

在while循环中,您可以像记录一样经常循环

while not AdoQuery.eof do

然后你访问Field

ADOQuery.Fields[i]

i代表当前的“记录编号”......

这会在任何程序中崩溃,只取决于查询的记录数与查询的字段数之间的关系...一旦记录计数高于字段数,它就会崩溃......

for循环是此修复程序的一部分......

但是,由于您不提供信息是否需要一条记录的所有字段或所有记录的所有字段都为resultset,因此很难提供固定代码...