2014-04-08 57 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,否则不需要大写。 –