2011-07-27 52 views
-3

在這種情況下,我有一些代碼在現有程序中沒有問題,但在新程序中使用它時會拋出一個異常。這段代碼有什麼問題?

它可能不是最好的代碼,但它是工作在日常使用...

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和布爾結果沒有被使用,但它工程...

....先前的方案,但在一個新的叫當thows異常...

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循環&繼續前進,但我想明白髮生了什麼問題....有人可以向我解釋嗎?由於

+0

嗯,沒有評論,沒有答案和一個投票。讓我想知道他爲什麼低調。並且讓我想建議沒有解釋就不允許下調。這只是良好的禮儀,並可以從這樣的解釋 – Mawg

+0

傾斜,你已經有2個答案... – Yahia

+1

不是當時沒有評論downvoted,我沒有。我喜歡這個網站,但是有時候這個網站的運行和運行... – Mawg

回答

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;它從一個記錄中抓取所有字段。

如果我必須猜測在第一個循環中導致異常的原因,我會說你的數據集中的記錄(行)比字段(列)多,所以經過足夠的迭代後,i最終結束在ADOQuery.Fields.Count,你會得到一個索引超出界限的錯誤。

你究竟想在這裏做什麼?

+0

+1同意,他們是不同的。 Ooops,colums/rows ...你是對的。這看起來像問題。我會重新編碼它,但是你能指點我一些MySql訪問的代碼嗎? Obiosusly,我需要它 – Mawg

+1

@Mawg:我不太瞭解MySQL。再次,你想要做什麼? –

+0

你找到了答案!我查看了舊代碼,並且該函數只用一個quey調用,它會返回一行中的單個列。當新項目想要返回多列行(每個數據庫一個)時,所以你對我和ADOQuery.Fields.Count是正確的 – Mawg

4

在你經常因爲有循環的while循環是記錄

while not AdoQuery.eof do 

但你接入領域

ADOQuery.Fields[i] 

i表示當前的「備案號」 ..

這隻會在任何程序中崩潰,這取決於查詢的記錄計數與查詢的字段計數之間的關係......儘快戰績計數大於領域指望它崩潰更高...

for循環是定爲這部分...

但因爲你沒有提供的信息是否你需要一個所有領域記錄或所有記錄作爲resultset很難提供固定碼各個領域......

+0

+1謝謝。我看到我的方式現在的錯誤 – Mawg