Как избежать дублирования дополнений к именам столбцов в 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
действительно невероятно универсальный класс. Это всегда немного удивляет, какое использование вы можете найти для него...