Array
Alguem poderia por favor me dar uma breve explicação sobre como trabalhar com arrays na manipulação de um banco de dados?
:cry: :cry:
:cry: :cry:
Flavia_mococa
Curtidas 0
Respostas
Jc
26/05/2004
Olá, você poderia ser mais expifica com relação ao uso (o que gostaria de fazer com arrays).
Té +
Té +
GOSTEI 0
Flavia_mococa
26/05/2004
Olá JC, tudo bem?
Eu gostaria de utilizar arrays nas consultas ao banco de dados.
Como quase 90¬ das tabelas deste banco tem um numero elevado de registro acho que seria mais conveniente trabalhar com arrays já que o acesso a memoria é bem mais rápido do que o acesso ao banco.
Meu problema é que eu tenho uma boa noção em array simples sem utilização de banco, mais agora array dinamico com acesso a banco eu não tenho nenhuma noção.
Voce poderia me ajudar?
Procurei alguns tutoriais na net mais achei apenas artigos sobre array simples, que não me ajuda neste caso.
:wink:
Eu gostaria de utilizar arrays nas consultas ao banco de dados.
Como quase 90¬ das tabelas deste banco tem um numero elevado de registro acho que seria mais conveniente trabalhar com arrays já que o acesso a memoria é bem mais rápido do que o acesso ao banco.
Meu problema é que eu tenho uma boa noção em array simples sem utilização de banco, mais agora array dinamico com acesso a banco eu não tenho nenhuma noção.
Voce poderia me ajudar?
Procurei alguns tutoriais na net mais achei apenas artigos sobre array simples, que não me ajuda neste caso.
:wink:
GOSTEI 0
Rômulo Barros
26/05/2004
[b:31c83ebf8e]Flávia_mococa escreveu:[/b:31c83ebf8e]
Utilizando DBX, você também poderá trabalhar em cache... ... ...
Utilize o método [color=red:31c83ebf8e]SetLength(MeuArray,Query.RecorCount -1)[/color:31c83ebf8e] para criar dinamicamente os seus arrays.
Como quase 90¬ das tabelas deste banco tem um numero elevado de registro acho que seria mais conveniente trabalhar com arrays já que o acesso a memoria é bem mais rápido do que o acesso ao banco.
Utilizando DBX, você também poderá trabalhar em cache... ... ...
Utilize o método [color=red:31c83ebf8e]SetLength(MeuArray,Query.RecorCount -1)[/color:31c83ebf8e] para criar dinamicamente os seus arrays.
GOSTEI 0
Flavia_mococa
26/05/2004
Voce pode me explicar como fazer isso?
GOSTEI 0
Vinicius2k
26/05/2004
Flavia,
Um exemplo do que o UI lhe falou, só não tenho certeza se é exatamente o que vc pretende...
Espero ter ajudado...
T+
Um exemplo do que o UI lhe falou, só não tenho certeza se é exatamente o que vc pretende...
procedure TForm1.Button1Click(Sender: TObject); var nome, email: Array of String; i,n: integer; begin // Determinando o tamanho dos Arrays... n:= ADOQuery1.RecordCount; SetLength(nome, n); SetLength(email, n); // Loop na Query... i:= 0; with ADOQuery1 do begin First; while not Eof do begin nome[i]:= FieldByName(´nome´).AsString; email[i]:= FieldByName(´email´).AsString; Next; inc(i); end; end; // Como exemplo : colocando o Array num Memo... for i:= 0 to (n-1) do Memo1.Lines.Add(nome[i] + ´ - ´ + email[i]); end;
Espero ter ajudado...
T+
GOSTEI 0
Flavia_mococa
26/05/2004
O problema é que vc já me passou o ´codigo pronto´ e oque eu queria era entender como o array dinamico funciona e como se relaciona a tabela com o array, entende. Assim futuramente quando eu precisar usar novamente os arrays eu vou saber fazer sem problemas :)
Vc´s poderiam me ajudar? :wink:
Vc´s poderiam me ajudar? :wink:
GOSTEI 0
Vinicius2k
26/05/2004
Flávia,
1 - declara o array sem determinar tamanho...
2 - já dentro do procedimento ou função vc determina o tamanho com a função SetLenght()... é vc que vai dizer qual o tamanho e como vc quer atribuir a eles um recordset, a quantidade de elementos do array vai ser a quantidade de registros do recordset...
3 - para atribuir o recordset ao array vc move o cursor para o primeiro registro e faz o loop até q seja final atribuindo o valor do campo do recordset ao array... para saber a qual elemento do array vou atribuir o valor usei um contador ´i´ que é incrementado a cada passagem de registro...
essa é a explicação do código... eh isso q vc quer?
1 - declara o array sem determinar tamanho...
2 - já dentro do procedimento ou função vc determina o tamanho com a função SetLenght()... é vc que vai dizer qual o tamanho e como vc quer atribuir a eles um recordset, a quantidade de elementos do array vai ser a quantidade de registros do recordset...
3 - para atribuir o recordset ao array vc move o cursor para o primeiro registro e faz o loop até q seja final atribuindo o valor do campo do recordset ao array... para saber a qual elemento do array vou atribuir o valor usei um contador ´i´ que é incrementado a cada passagem de registro...
essa é a explicação do código... eh isso q vc quer?
GOSTEI 0
Chico Gois
26/05/2004
Só complementado o que foi escrito pelos colegas
Ps. Texto retirado da net
Domine o array dinamico :)
Estou começando do princípio que você já conheça os princípios do array ´simples´, ou seja, array fixo (Exemplo abaixo)
Procedure Tform1.Button1Click (Sender: Tobject) ;
var
Dias_de_Semana: array[1..7] of String;
DiaNo: Integer;
begin
{Inicializa o array com nomes dos dias da semana }
Dias_de_Semana [1] := ´Domingo´ ;
Dias_de_Semana [2] := ´Segunda-feira´ ;
Dias_de_Semana [3] := ´Terça-feira´ ;
Dias_de_Semana [4] := ´Quarta-feira´ ;
Dias_de_Semana [5] := ´Quinta-feira´ ;
Dias_de_Semana [6] := ´Sexta-feira´ ;
Dias_de_Semana [7] := ´Sábado´ ;
// Retorna o número da semana atual
DiaNo :=DayOfWeek (Date) ;
ShowMessage(´ Hoje é ´ + Dias_de_Semana [DiaNo] ) ;
Caso você não entenda o exemplo acima, então aconselho a estudar o Array primeiramente. Existem na Internet muitos materiais que ensinam os princípios do array.
Bom se esta seguro do uso da array, vamos em frente.
Array Dinâmico, significa que você pode alterar um array durante a execução, alterando o tamanho ou adicionando/retirando informações.
No Delphi, existem funções que servem também para ajudar nestas necessidades.
Utilizaremos dentre as existentes, as funções:
SETLENGTH;
HIGH;
LOW;
LENGTH.
Veremos a seguir, detalhadamente o uso de cada uma delas.
Vamos a prática!!!
Dentro do form, insira um button e dê duplo clique no mesmo.
Insira o código:
procedure TForm1.Button1Click(Sender: TObject);
var
ContadorDinamico : array of string; //Indico o meu vetor (ContadorDinamico) como array do tipo string.
Begin
// SetLength aqui, serve para pegar a quantidade máxima que o ContadorDinamico suportará, ou seja, de 0 a 9 posições..
SETLENGTH(ContadorDinamico,10);
// LENGTH tem a finalidade de capturar a quantidade total definida em SETLENGTH
ShowMessage(IntToStr(LENGTH(ContadorDinamico)));
end;
Agora no próximo exemplo, veja a utilidade das funções HIGW e LOW.
procedure TForm1.Button2Click(Sender: TObject);
var
ContadorDinamico : array of string; //Indico o meu vetor (ContadorDinamico) como array do tipo string.
Begin
// SetLength aqui, serve para pegar a quantidade máxima que o ContadorDinamico suportará, ou seja, de 0 a 9 posições..
SETLENGTH(ContadorDinamico,10);
// LENGTH tem a finalidade de capturar a quantidade total definida em SETLENGTH
ShowMessage(IntToStr(LENGTH(ContadorDinamico)));
// Apresenta a última posição, ou seja, 9, enquanto o LENGTH apresenta o tamanho suportado.
ShowMessage(inttostr(HIGH(contadordinamico)));
// Apresenta a primeira posição, ou seja, 0.
showmessage(inttostr(LOW(contadordinamico)));
end;
Nota: Um Array de tamanho 0 (Zero) é um array NIL, ou seja, nulo.
Ex. SETLENGTH(ContadorDinamico,0);
Vamos praticar mais.
Imagine que você precise, através de um array, contar os caracteres digitados em um edit.
Insira no form um edit e um novo botão que receberá o código abaixo:
var
ContadorDinamico : array of string;
Begin
SETLENGTH(ContadorDinamico,length(edit1.text));
showmessage(inttostr(length(contadordinamico)));
end;
O length pega a quantidade de caracteres do edit e repassa esta informação para o vetor, armazendo pelo SetLength.
Na segunda linha o length conta o que foi armazenado pelo SetLength.
Atenção! Imaginemos que o texto do edit seja ´edit1´. O SetLength armazenou o vetor de 0 a 5, contudo o length conta iniciando do 1.
Caso tenha ainda dúvidas, coloque abaixo da linha do show message, esta 2 (duas) linhas para entender.
showmessage(inttostr(low(contadordinamico)));
showmessage(inttostr(high(contadordinamico)));
Agora basta aprimorar:
Veja um exemplo mais complexo, utilizando um form com um listbox e um botão no qual vai o código abaixo:
var
Matriz : Array of array of String;
i, j: integer;
begin
i:=0;
j:=0;
SetLength( Matriz, 10 );
For i:= Low(Matriz) to High(Matriz) do
begin
listbox1.Items.Add(´***** ´+inttostr(j)+´ Decimal com final ´+inttostr(i)+´ *****´);
SetLength( Matriz[i], 10 );
For j:= Low(Matriz[i]) to High(Matriz[i]) do
Begin
Matriz[i,j] := IntToStr(i) + ´,´ + IntToStr(j) + ´ ´;
sleep(2);
listbox1.Items.Add(inttostr(j)+inttostr(i));
end;
end;
end;
Um exemplo prático para o qual você poderia utilizar, seria para verificar entre 2(duas) StringList se a contagem é a mesma.
Ex.
//Utilizo 2 Stringlist. Uma para jogar os campos e outro para os dados.
StringListCampo.Add(´Nome´); StringListDado.Add(editNome.text);
StringListCampo.Add(´Ender´); StringListDado.Add(edtEnder.text);
//Chamo a função
InsertSQL(StringListCampo,StringListDado);
// A função verifica se a quantidade de campo é igual para os dados.
function InsertSQL(Tabela: String; Campo: array of string; Valor: array of variant): String;
var
lstCampo, lstValor: TStringList;
Begin
if Length(Campo) <> Length(Valor) then
ShowMessage(´O número de elementos nas listas de campos e valores é diferente.´);
A base já foi passada, agora é só praticar.
Ps. Texto retirado da net
GOSTEI 0
Flavia_mococa
26/05/2004
O que eu quero seria mais ou menos oque vc´s me explicaram, so tive um pequeno problema. Iniciei o código:
procedure TFrmCaixa.Edit3Change(Sender: TObject);
var fornecedor, RazaoSocial, TIPODOCRF, NUMDOCRF, Fantasia: Array of String;
f,r: integer;
begin
f:= DModul.QForn.RecordCount;
SetLength(fornecedor, f);
SetLength(RazaoSocial, f);
SetLength(Fantasia, f);
SetLength(TIPODOCRF, f);
SetLength(NUMDOCRF, f);
//Loop na ADOQuery
r:=0;
DModul.QForn.First;
while not eof do
Begin
fornecedor[f]:=DModul.QForn //meu problema foi exatamente aqui
Nao consegui achar a propriedade FieldByName para seguir com o código...
E depois que eu terminar esta parte do codigo posso fazer uma consulta neste array ? Como proceder?
Desculpe postar estas perguntas bovas, mais é que tenho duvidas...
:roll: :wink:
procedure TFrmCaixa.Edit3Change(Sender: TObject);
var fornecedor, RazaoSocial, TIPODOCRF, NUMDOCRF, Fantasia: Array of String;
f,r: integer;
begin
f:= DModul.QForn.RecordCount;
SetLength(fornecedor, f);
SetLength(RazaoSocial, f);
SetLength(Fantasia, f);
SetLength(TIPODOCRF, f);
SetLength(NUMDOCRF, f);
//Loop na ADOQuery
r:=0;
DModul.QForn.First;
while not eof do
Begin
fornecedor[f]:=DModul.QForn //meu problema foi exatamente aqui
Nao consegui achar a propriedade FieldByName para seguir com o código...
E depois que eu terminar esta parte do codigo posso fazer uma consulta neste array ? Como proceder?
Desculpe postar estas perguntas bovas, mais é que tenho duvidas...
:roll: :wink:
GOSTEI 0
Vinicius2k
26/05/2004
Flávia,
Não se preocupe em perguntar, é assim q aprendemos... :wink:
Não vejo muita lógica em vc não encontrar a propriedade FieldByName... se vc estiver tendo alguma mensagem de erro do compilador é um problema e postar aqui a mensagem vai ajudar-nos a entender, mas se vc só está preocupada por ela não ter aparecido no CodeCompletion do Delphi, não se preocupe, isso as vezes acontece dependendo de qual o tipo de variável vc está atribuindo o valor... pode seguir seu código que vai dar certinho...
Após montado o Array vc pode efetuar a consulta, jogando os dados numa TStringList (no exemplo q lhe passei joguei num memo)... Apenas sugiro que vc pesquise, talvez aqui mesmo, sobre StringLists pq desta classe eu não entendo quase nada, então não devo poder ajudar muito...
Qualquer problema poste novamente !
T+
Não se preocupe em perguntar, é assim q aprendemos... :wink:
Não vejo muita lógica em vc não encontrar a propriedade FieldByName... se vc estiver tendo alguma mensagem de erro do compilador é um problema e postar aqui a mensagem vai ajudar-nos a entender, mas se vc só está preocupada por ela não ter aparecido no CodeCompletion do Delphi, não se preocupe, isso as vezes acontece dependendo de qual o tipo de variável vc está atribuindo o valor... pode seguir seu código que vai dar certinho...
Após montado o Array vc pode efetuar a consulta, jogando os dados numa TStringList (no exemplo q lhe passei joguei num memo)... Apenas sugiro que vc pesquise, talvez aqui mesmo, sobre StringLists pq desta classe eu não entendo quase nada, então não devo poder ajudar muito...
Qualquer problema poste novamente !
T+
GOSTEI 0
Bacalhau
26/05/2004
Só para complementar um pouco a coisa. A colega definiu uma série de arrays dinâmicas que parecem referenciar informação sobre um mesmo registo. Então porque não criar um record dessa informação? Ficava mais ou menos assim:
type forn = record
fornecedor : String;
RazaoSocial : String;
TIPODOCRF : String;
NUMDOCRF : String;
Fantasia : String;
end; // fim da definição de registo
var F : array of forn;
A partir daqui, fica mais fácil visualizarmos o nosso trabalho. Espero ter ajudado e não complicado... :oops:
type forn = record
fornecedor : String;
RazaoSocial : String;
TIPODOCRF : String;
NUMDOCRF : String;
Fantasia : String;
end; // fim da definição de registo
var F : array of forn;
A partir daqui, fica mais fácil visualizarmos o nosso trabalho. Espero ter ajudado e não complicado... :oops:
GOSTEI 0
Aroldo Zanela
26/05/2004
Colega,
Qual é o propósito de se utilizar arrays no seu caso agora? Ou seja, quais são os requisitos funcionais que você precisa satisfazer? Dependendo do que você precisa resolver em termos de negócio, acredito que o Delphi permite utilizar formas mais simples e de melhor performance.
Qual é o propósito de se utilizar arrays no seu caso agora? Ou seja, quais são os requisitos funcionais que você precisa satisfazer? Dependendo do que você precisa resolver em termos de negócio, acredito que o Delphi permite utilizar formas mais simples e de melhor performance.
GOSTEI 0
Nildo
26/05/2004
Amigo,
Você quer um acesso rápido ao banco de dados e por isso quer salvar tudo na memória né? Ok, não se esqueça que você vai ter que ler todo o banco pra poder jogar nessa Array... Ahh e não se esqueça que pode acabar a memória disponível, sendo que você vai colocar Todo o banco lá...
Você quer um acesso rápido ao banco de dados e por isso quer salvar tudo na memória né? Ok, não se esqueça que você vai ter que ler todo o banco pra poder jogar nessa Array... Ahh e não se esqueça que pode acabar a memória disponível, sendo que você vai colocar Todo o banco lá...
GOSTEI 0
Flavia_mococa
26/05/2004
Amigos, o que eu quero é o seguinte:
Como no banco de dados que uso as tabelas tem um numero elevado de registro uma consulta utilizando a adoquery fica muito lenta. Entao eu queria que na criação do form (no evento oncreat do form) fosse ´criada´ a array com todos os dados da tabela que vou usar para fazer as consultas, depois no evento onexit do form eu iria ´destruir´ esse array liberando a memoria para ser usada novamente.
Voces estao sendo o maximo em me ajudar.
Desculpe estar fazendo tantas perguntas, mais é que tive apenas uma pequena noção de delphi na escola onde estudo, gostei e agora estou tentando me aprofundar nesta linguagem.
Muito obrigada mesmo pela força que estao me dando :wink:
Como no banco de dados que uso as tabelas tem um numero elevado de registro uma consulta utilizando a adoquery fica muito lenta. Entao eu queria que na criação do form (no evento oncreat do form) fosse ´criada´ a array com todos os dados da tabela que vou usar para fazer as consultas, depois no evento onexit do form eu iria ´destruir´ esse array liberando a memoria para ser usada novamente.
Voces estao sendo o maximo em me ajudar.
Desculpe estar fazendo tantas perguntas, mais é que tive apenas uma pequena noção de delphi na escola onde estudo, gostei e agora estou tentando me aprofundar nesta linguagem.
Muito obrigada mesmo pela força que estao me dando :wink:
GOSTEI 0
Nildo
26/05/2004
Flavia, já parou para pensar que voce vai ter que passar por TODOS os registros da tabela (que é gigante) para armazenar na Array, diminuindo assim consideravelmente a memória disponível, e perdendo MUITO tempo somente na criação do formulário? Pois você vai ter que fazer isso no FormCreate
GOSTEI 0
Vinicius2k
26/05/2004
Flávia,
Em relação ao conselho que o Aroldo e o nildo lhe deram e com base no que vc relatou que pretende, acho (é só minha opinião) que vc não terá o resultado esperado... ao varrer toda a tabela para preencher o array e posteriormente varrer todo o Array em busca de um dado, vc irá comprometer mais a performance do que se usasse uma TDBGrid, por exemplo...
O princípio básico do desenvolvimento de aplicações Cliente/Servidor é trazer para a aplicação apenas os dados necessários e para isso usamos selects com where, like, etc... mas existem outras formas de se obter um melho desempenho mesmo com um ´select * from tabela´ (sem where)... um exemplo : quando comecei a utilizar DBExpress eu achei um verdadeiro caos o TClientDataSet... muito lento, quando precisava de fossem recuperados todos os registros da tabela, até que estudei-o um pouco e encontrei a propriedade ´PacketRecords´ a qual seto para 1000, por exemplo, e a performance cresce vertiginosamente...
Dependendo da camada de acesso que vc está utilizando, a performance pode ser melhorada sem o uso de rotinas com arrays...
T+
Em relação ao conselho que o Aroldo e o nildo lhe deram e com base no que vc relatou que pretende, acho (é só minha opinião) que vc não terá o resultado esperado... ao varrer toda a tabela para preencher o array e posteriormente varrer todo o Array em busca de um dado, vc irá comprometer mais a performance do que se usasse uma TDBGrid, por exemplo...
O princípio básico do desenvolvimento de aplicações Cliente/Servidor é trazer para a aplicação apenas os dados necessários e para isso usamos selects com where, like, etc... mas existem outras formas de se obter um melho desempenho mesmo com um ´select * from tabela´ (sem where)... um exemplo : quando comecei a utilizar DBExpress eu achei um verdadeiro caos o TClientDataSet... muito lento, quando precisava de fossem recuperados todos os registros da tabela, até que estudei-o um pouco e encontrei a propriedade ´PacketRecords´ a qual seto para 1000, por exemplo, e a performance cresce vertiginosamente...
Dependendo da camada de acesso que vc está utilizando, a performance pode ser melhorada sem o uso de rotinas com arrays...
T+
GOSTEI 0
Flavia_mococa
26/05/2004
Então como eu poderia melhorar a performance de uma consulta feita atraves de um adoquery? Tem alguma propriedade para isso?
GOSTEI 0
Paulo_amorim
26/05/2004
Olá
Creio que o primeiro passo seria avaliar se é realmente necessário trazer TODA a tabela quanod se inicia o Form... muitas vezes nem todos os registros serão usados...
Um banco bem estruturado não deixa tão lenta a leitura dos daods como um banco ´meia boca´...
Quem sabe ajude...
Até+
Creio que o primeiro passo seria avaliar se é realmente necessário trazer TODA a tabela quanod se inicia o Form... muitas vezes nem todos os registros serão usados...
Um banco bem estruturado não deixa tão lenta a leitura dos daods como um banco ´meia boca´...
Quem sabe ajude...
Até+
GOSTEI 0
Rômulo Barros
26/05/2004
Sem muitas palavras, basta vc utilizar querys com parâmetros, tipo:
Select Campos From Produtos Where CodProduto = :ACodigoProduto;
GOSTEI 0
Bacalhau
26/05/2004
Essa estratégia tem vantagens, mas tem alguns riscos.
1. primeiro, ao usar arrays dinamicas fica implicito que toda a tabela será carregada, todas as alterações serão feitas nas arrays e, finalmente, o conteúdo das arrays serão actualizados na tabela. Isto tem alguns problemas como a partilha de informação, falta de energia, etc.. Como controlar se 2 usuários acedem ao mesmo indice da array ao mesmo tempo?
2. Outra questão é o tamanho da tabela. Não seria melhor criar uns testes para ver se funciona, em vez de partir já para a solução? Tipo criar uma base MESMO gigantesca e ver quantos registos cabem na memória do computador?
abraço
bacalhau
1. primeiro, ao usar arrays dinamicas fica implicito que toda a tabela será carregada, todas as alterações serão feitas nas arrays e, finalmente, o conteúdo das arrays serão actualizados na tabela. Isto tem alguns problemas como a partilha de informação, falta de energia, etc.. Como controlar se 2 usuários acedem ao mesmo indice da array ao mesmo tempo?
2. Outra questão é o tamanho da tabela. Não seria melhor criar uns testes para ver se funciona, em vez de partir já para a solução? Tipo criar uma base MESMO gigantesca e ver quantos registos cabem na memória do computador?
abraço
bacalhau
GOSTEI 0