2014-04-08 104 views
2

我使用下面的代碼動態添加字段的數據集組件:避免重複列名附加

while not ibSQL.Eof do 
    fieldname := Trim(ibSql.FieldByName('columnnameofchange').AsString); 
    TDataSet.FieldDefs.Add(fieldname , ftString, 255); 
end 

問題是,我可能會重名那麼什麼是篩選副本的最簡單的方法和不添加已添加的重複項。

我希望不要通過TDataSet.FieldDefList的增加,因爲這將是每一個欄除了繁瑣的每一列穿越。並且可以有許多補充。

如果可能,請提供其他解決方案。如果沒有,那麼我堅持使用FieldDefList迭代。

我還會補充說,篩選SQL查詢中的重複項是一個選項,但不是所需的選項。

感謝

回答

4

TFieldDefs有一個方法IndexOf時給定的名稱字段不存在返回-1

+0

我嘗試了find方法,但是它在第一次發現嘗試時調用了一個GUI消息,說「Field'columnnameofchange'not Found」,然後該過程在其軌道中停止並且不再處理SQL中的任何更多記錄。如果fDataSet.FieldDefs.Find(fieldname)= nil那麼 fDataSet.FieldDefs.Add(fieldname,ftString,255); –

+0

你說得對。我一定是被繼承的TDefCollection的Find方法誤導了。在這種情況下,最好嘗試IndexOf並檢查-1。 –

+0

是的,這工作。謝謝 –

1

我反正張貼這是我寫完它,但在查詢清楚篩查是我對這個問題的偏好。

我有一點很難理解你的目標是什麼這麼原諒我,如果我不回答你的問題。而且,自從我定期使用Delphi以來,這已經有好幾年了,所以這絕對不是一個具體的答案。

如果您使用的TADOQuery(或任何TDataSet的你使用),在我希望我的解決辦法的辦法是做類似:

//SQL 
SELECT 
    a.field1, 
    a.... , 
    a.fieldN, 
    b.field1 as "AlternateName" 
FROM 
    Table a INNER JOIN Table b 
WHERE ... 

由於這點,它會自動使用AlternateName代替field1(因此碰撞你被迫通過索引或重命名列的工作

很顯然,如果你打開一個表來寫這不是一個很好的解決方案在我的經驗與德爾福的大部分困難可以用簡單的SQL技巧剝離出來,所以這個你不需要浪費時間玩田地。

本質上講,這只是做你的來源,而不是目的地做什麼,這是一個很大的挫折感更容易更新。

+0

儘管您描述了在查詢中調整列名的有效方法,但這與問題中描述的問題無關。如果您查看提供的源代碼,則可以看到結果集是迭代的,其中「字段名稱」取自一列的內容。實際上,「字段名稱」代表檢索的數據。 –

+0

是的,與問題無關。數據中的碰撞是可以接受的,如果你注意到我可以將許多垂直數據列變成一個寬水平行。這比較複雜,但通常情況就是這樣。 –

2

如果我理解正確的話,最簡單的方法很可能是把所有的現有字段名在TStringList。然後,您可以添加一個新的領域之前檢查是否存在,如果你加它,你只需添加名稱列表:

var 
    FldList: TStringList; 
    i: Integer; 
begin 
    FldList := TStringList.Create; 
    try 
    for i := 0 to DataSet.FieldCount - 1 do 
     FldList.Add(DataSet.Fields[i].FieldName); 

    while not ibSQL.Eof do 
    begin 
     fieldname := Trim(ibSql.FieldByName('columnnameofchange').AsString); 
     if FldList.IndexOf(fieldName) = -1 then 
     begin 
     FldList.Add(fieldName); 
     DataSet.FieldDefs.Add(fieldname , ftString, 255); 
     end; 
     ibSQL.Next; 
    end; 
    finally 
    FldList.Free; 
    end; 
end; 
0

我會做的就是保持一個TStringListSorted := trueDuplicates := dupError集。對於每個字段,在try塊內執行myStringList.Add(UpperCase(FieldName));,如果它引發異常,則知道它是重複的。

TStringList是一個非常多才多藝的課程。它總是有點出人意料所有你能找到它的用途...

+0

而不是捕捉異常,你應該檢查'TStrings.IndexOf' –

+1

如果它只是你需要的字段名,你可以簡單地將Stringlist Duplicates設置爲dupIgnore,並在循環後創建迭代StringList的FieldDefs。順便說一句,除非將CaseSensitive設置爲true,否則不需要大寫。 –