Как избежать дублирования дополнений к именам столбцов в TDataSet

Я динамически добавляю поля в TDataSet, используя следующий код:

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 когда поле с указанным именем не существует.

Если я вас правильно понимаю, возможно, проще всего было бы поместить все существующие имена полей в 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;

Я пишу это в любом случае, как только закончу писать, но четкое изучение запроса было моим предпочтением для этой проблемы.

У меня возникли проблемы с пониманием того, к чему ты стремишься, так что прости меня, если я не отвечу на твой вопрос. Кроме того, прошли годы с тех пор, как я регулярно использовал Delphi, так что это определенно не конкретный ответ.

Если вы используете TADOQuery (или какой-либо TDataSet, который вы используете), как я ожидаю, мой обходной путь должен был сделать что-то вроде:

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

В какой момент он автоматически использовал AlternateName вместо field1 (таким образом, столкновение, когда вы вынуждены работать по индексу или переименовать столбцы.

Очевидно, что если вы открываете таблицу для написания, это не очень хорошее решение. По моему опыту работы с Delphi большую часть трудностей можно было бы устранить с помощью простых трюков SQL, чтобы вам не пришлось тратить время на игры с полями.

По сути, это просто делает то, что вы делаете в источнике, а не в месте назначения, и это гораздо проще для обновления.

Что бы я сделал, это сохранить TStringList с Sorted := true а также Duplicates := dupError задавать. Для каждого поля сделайте myStringList.Add(UpperCase(FieldName)); внутри блока try, и если он выдает исключение, вы знаете, что это дубликат.

TStringList действительно невероятно универсальный класс. Это всегда немного удивляет, какое использование вы можете найти для него...

Другие вопросы по тегам