Lendo a estrutura do conjunto de dados sem ler seus dados
-
22-09-2019 - |
Pergunta
Cenário:
Quero adicionar um campo calculado ao conjunto de dados (qualquer) em tempo de execução. Não conheço nenhuma outra maneira de obter uma estrutura de conjunto de dados além de executar DataSet.Open
método.
Mas o Open
O método faz com que, pelo menos, uma linha de dados precise ser transferida do servidor para o cliente. Então eu preciso fechar o conjunto de dados, adicionar campo e reabri -lo. Esta é uma sobrecarga desnecessária na minha opinião. Existe um jeito melhor de fazer isso? Não que eu queira adicionar um campo calcado a qualquer conjunto de dados e não conheço sua estrutura antes da abertura.
No pseudocódigo, é assim:
DataSet.Open;
DataSet.Close;
RecreateFieldsStructure;
AddCalculatedField;
DataSet.Open;
Obrigado pelo seu tempo.
Solução
Você pode usar o método DataSet.FieldDefs.Update. Isso ainda envolverá alguma transferência de dados, mas nenhuma linha será buscada. Você pode chamar esse método no evento anterior do TDataset e também adicionar os campos calculados lá.
Aqui está um pequeno exemplo que funciona para mim:
procedure TDataModule.cdsExampleBeforeOpen(DataSet: TDataSet);
var I: Integer;
TmpField: TDateTimeField;
begin
// Get field definitions from the server
DataSet.FieldDefs.Update;
// Add calculated field
TmpField := TDateTimeField.Create(DataSet);
with TmpField do
begin
Name := 'Date';
FieldName := 'Date';
DisplayLabel := 'Date';
DisplayFormat := 'ddd ddddd';
Calculated := True;
end;
TmpField.DataSet := DataSet;
// Create fields from field definitions
for I := 0 to DataSet.FieldDefs.Count - 1 do
DataSet.FieldDefs[I].CreateField(DataSet);
end;
Outras dicas
Se eu entendi bem sua pergunta; Você deseja ver/conhecer a estrutura das tabelas antes de chamar o método Adoquery (aberto). Se isso quiser, você pode usar os métodos de adoconexão como (getFieldNames) e aqui um exemplo de como obter os nomes de campo da tabela (EMP):
procedure TForm2.Button1Click(Sender: TObject);
var
lstFields: TStringList;
begin
lstFields := TStringList.Create;
try
ADOConnection1.GetFieldNames('EMP', lstFields);
finally
lstFields.Free;
end;
end;
Em seguida, todos os nomes dos campos estão agora em (Lstfields). Espero que isso ajude.
Cumprimentos.