Dúvida com select

04/02/2006

0

Tenho uma tabela1 com os campos nome(string) e composição(string), no campo composição pode haver entre 1 e N componentes, separados por vírgula.
Tenho uma tabela2 com os campos composição1 (string) com apenas 1 palavra, composição2 (string) com apenas 1 palavra e o campo reação(string).
Agora a pesquisa: a pessoa digita num edit1 o nome1, e no edit2 o nome2, ao clicar um botão, deverá fazer o seguinte:
1) buscar o nome1 na tabela1, pegar todos as composições contidas no campo composição e montar uma matriz X de M elementos (de acordo com a quantidade de componentes contidos neste campo);
2) buscar o nome2 na tabela1, pegar todos as composições contidas no campo composição e montar uma matriz Y de N elementos (de acordo com a quantidade de componentes contidos neste campo);
3) montar uma combinação entre as duas matrizes, digamos uma matriz Z para jogar o resultado da pesquisa neste matriz;
4) pegar a matriz X[I] e buscar na tabela2 no campo composição1, se achar então pega a matriz Y[I] e busca na tabela2 no campo composição2, caso ache pega o resultado contido na tabela2, campo reação e joga na matriz Z[I].
Eu não tenho problema em criar as matrizes, nem em criar a combinação, o meu problema está em construir esta SQL


Edilcimar

Edilcimar

Responder

Posts

04/02/2006

Marco Salles

está dando um erro aqui Query1.ParamByName(´Comp1´).AsString:=X[I - 1]; Query1.ParamByName(´Comp2´).AsString:=Y[J - 1]; nesta linha, dizendo que query1.parameter ´Comp2´ not found, isto na primeira passada do loop, porém se dou um showmessage no y[j-1] ele me mostra o valor


o código que lhe passei não tem isto

outra coisa edicilmar , voltei aqui so para te dizer isto:

1)para testar deve cadastrar a composicao na tabela1 sem deixar espaços,
isto porque estamos trabalhando com caracter
Assimdev-se ter por exemplo
Produto1 A;S;D;F
Produto2 H;J;K;L

2)outra coisa que quero deixar levantado e sobre esta citação
//esta é a lei de formação servira para implementar Z****** Indice:=(i*j)+(i-1)*(3-j); //A formula anteiror no meu conceito e de extrema importancia para

esta formula não esta certa.. Vou desenvolver uma outra formula e post amanha de manha

[b:db5ac3f1c8]Por mais modifique a sql para o código que eu postei.. Note que to trabalhando com duas query[/b:db5ac3f1c8] Uma consulta na tabela1 e outra na tabela2

É claro que este cídigos no fim podem ser todos Maximizados.. Mas isto é para ver aonde podemos chegar

Boa sorte


Responder

04/02/2006

Edilcimar

devido ao fato de que troquei apenas os nomes dos campos, a tua está dando erro não sei se de parênteses, espaço, ou outra coisa, já troquei de todas as formas mas o erro persiste, eis aqui a minha, e creio que o Z vai funicionar

K := 0;
For I := 0 to TamanhoX - 1 do
Begin
For J := 0 to TamanhoY - 1 do
Begin
Query1.Close;
Query1.SQL.Clear;
Query1.Sql.Add(´Select * From Reacao´);
Query1.Sql.Add(´Where ((ELEMENTO1 =:Comp1 ´);
Query1.Sql.Add(´And (ELEMENTO2 =:Comp2)) ´);
Query1.Sql.Add(´Or ((ELEMENTO1 :=Comp2) ´);
Query1.Sql.Add(´And (ELEMENTO2 :=Comp1))´);
Query1.ParamByName(´Comp1´).AsString := X[I];
Query1.ParamByName(´Comp2´).AsString := Y[J];
Query1.Prepare;
Query1.Open;

//esta é a lei de formação servira para implementar Z******
// Indice:=(i*j)+(i-1)*(3-j);
//A formula anteiror no meu conceito e de extrema importancia para
//a formação da futura Matriz Z

If Query1.FieldByName(´RESULTADO´).AsString <> ´´ then
Z[K] := Z[K] + Query1.FieldByName(´RESULTADO´).AsString
Else
Z[K] := Z[K] + ´Sem Reação Conhecida´;
// Memo4.Lines.Add(Query2.FieldByName(´Reacao´).AsString)
//Z[i,Indice]:=query2.fieldByName(´Reacao´).AsString
//nada foi encontrado
// Else
// Memo4.Lines.Add(´´);
// Z[I,indice]:=´´;
End;
End;
For I := 1 to Length(Z) do
Memo1.Lines.Add(Z[K]);


Responder

04/02/2006

Edilcimar

corrigindo aqui
If Query1.FieldByName(´RESULTADO´).AsString <> ´´ then
Z[K] := Z[K] + Query1.FieldByName(´RESULTADO´).AsString
Else
Z[K] := Z[K] + ´Sem Reação Conhecida´;
K := K + 1;


Responder

04/02/2006

Marco Salles

A formação de Z , se voce quiser uma Matriz Z(n,2) ja da para calcular o Indice.. Desde que se defina Z como sendo em duas dimensoes. O que parece que voce não o Fez


corrigindo aqui If Query1.FieldByName(´RESULTADO´).AsString <> ´´ then Z[K] := Z[K] + Query1.FieldByName(´RESULTADO´).AsString Else Z[K] := Z[K] + ´Sem Reação Conhecida´; K := K + 1;


Eu não entendi.. Deu para chegar em algum lugar ou não ???

devido ao fato de que troquei apenas os nomes dos campos, a tua está dando erro não sei se de parênteses,


o meu select2 Deve ser refletido,, eu fiz sem testar. A idéia e testar o valor de X[I] Y[j] simultaneamente

[b:97fa5e45aa](X[i] na Composica1 e Y[j] na composicao2)Or
(X[i] na Composica2 e Y[j] na composicao1)[/b:97fa5e45aa]

Pelo que nos combinamos logo no inicio lembra


Responder

05/02/2006

Edilcimar

Não fiz uma matriz bidimensional, não há necessidade, basta pegar a matriz Z e acrescentar o texto da reação com o texto já existente, tipo
Z[1] := A+B= (isto já foi colocado antes) + ´dor de barriga´ isto deverá ser colocado aqui, caso a reação A+B não exista então será colocado ´sem reação conhecida´
Isto já foi colocado para quando a sql venha a funcionar, quanto da pesquisa dos 2 campos x[i] e y[j], não vejo problema algum


Responder

05/02/2006

Marco Salles

bom dia

mudei algumas instruçoes..

alem disso testei

parece Ok

so precisa colocar pimenta a seu gosto

type
A = Array of string;

var
X : A;
tamanhox:integer;
Y : A;
tamanhoy:integer;
Z : A;

procedure CriarMatriz(var B:A;var tamanho:integer;Composicao:String);
var
i,indiceanterior,q:integer;
texto:String;
begin
tamanho:=0;
setlength(B, 100);
i:=0;
indiceAnterior:=1;
q:=0;
while i <= (length(composicao)-1) do
 begin
    if composicao[i]=´;´ then
      begin
        texto:=copy(composicao,indiceanterior,i - indiceAnterior);
        indiceAnterior:=i+1;
        B[q]:=Trim(texto);
        q:=q+1;
        tamanho:=Tamanho+1;
      end;
    i:=i+1;
 end;
if length(composicao) > 0 then
  begin
    if composicao[i]=´;´ then
      texto:=copy(composicao,indiceanterior,i-indiceAnterior)
    else
      texto:=copy(composicao,indiceanterior,(i+1) - indiceAnterior);
    B[q]:=Trim(texto);
    tamanho:=Tamanho+1;
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
i,j,indice:integer;
begin
Query1.Close;
Query1.SQL.Clear;
Query1.Sql.Add(´Select *From  Tabela1´);
Query1.Sql.Add(´Where Produto=:NomePrimeiroProduto´);
Query1.ParamByName(´NomePrimeiroProduto´).asstring:=edit1.text;
Query1.Sql.Add(´OR Produto=:NomesegundoProduto´);
Query1.ParamByName(´NomesegundoProduto´).asstring:=edit2.text;
Query1.Prepare;
Query1.open;
if query1.RecordCount = 2 then
  begin
   CriarMatriz(X,tamanhox,query1.FieldByName(´Composicao´).asstring);
   Query1.Next;
   CriarMatriz(y,tamanhoy,query1.FieldByName(´Composicao´).asstring);
   setlength(Z, 100);
   indice:=0;
   for i:=0 to tamanhox-1 do
    begin
      for j:=0 to tamanhoy-1 do
        begin
          Query1.Close;
          Query1.SQL.Clear;
          Query1.Sql.Add(´Select *From  Tabela2´);
          Query1.Sql.Add(´Where ((Composicao1=:Comp1)and(Composicao2=:Comp2))or((Composicao1=:Comp2)and(Composicao2=:Comp1))´);
          Query1.ParamByName(´Comp1´).asstring:=X[i];
          Query1.ParamByName(´Comp2´).asstring:=Y[J];
          Query1.Prepare;
          Query1.open;
          Z[indice]:=X[i]+´  ´+Y[J];
          if query1.fieldByName(´Reacao´).AsString <> ´´ Then
             Z[Indice]:=Z[Indice]+´  ´+query1.fieldByName(´Reacao´).AsString
          //nada foi encontrado
          else
            Z[indice]:=Z[Indice]+´ Sem Reação Conhecida´;
          Indice:=indice+1;
        end;
   end;
  for i:=0 to indice do
    memo1.Lines.Add(Z[i]);
 end
else
 showmessage(´Pesquisa concluida . Nada fora encontrado´);
end;


testei e a principio foi satisfatorio

O que eu mudei

1) Z não é mais bidiemensional

2) Maximizei o código

3)utililei a mesma procedure criar Matriz Para X e Y

4)A combinação Matriz Z , não precisa mais de uma função de Combinação.. Ela é contruida no próprio Loop

5)Importante ... Coloquei toda a instrução do segundo Select dentro de Uma mesma Linha... Sofro em tentar separa-lo e ja ha muito tempo atrás abri um tópico sobre isso
[b:6df99c5ec5]//Mesma Linha[/b:6df99c5ec5]
Query1.Sql.Add(´Where ((Composicao1=:Comp1)and(Composicao2=:Comp2))or((Composicao1=:Comp2)and(Composicao2=:Comp1))´);


6)Alterei a função CriarMatriz

7)Alterei no primeir sql
query1.FieldByName(´Produto´).asstring para
query1.FieldByName(´Composicao´).asstring
, pois as matrizes devem ser criadas a partir da composição e naõ do nome do Produto

8)A intrução
if query1.RecordCount = 2 then

é a gosto e há como fazer outros testes , usando o Próprio
[b:6df99c5ec5]query1.FieldByName(´Composicao´).asstring <> ´´ Faça Senão Não Faça[/b:6df99c5ec5]

9)Emfim , acho que não ira ter problemas


Responder

05/02/2006

Edilcimar

FUNCIONOU
aqui está a que eu terminei de modificar, vou testar a sua função, a minha está funcionando perfeitamente inclusive na inversão das posições na tabela;
Marcos, grato pela ajuda, valeu pela força


procedure TForm4.Button2Click(Sender: TObject);
var
I, J, K, TamanhoX, TamanhoY : Integer;
Texto, Temp : String;
X, Y, Z : array of string;
begin
Temp := ´´;
Memo1.Lines.Clear;
J := 1;
SetLength(X,1);
SetLength(Y,1);
With Table1 do
Begin
If Locate(´PRODUTO´,Edit1.Text,[]) then
Texto := Trim(FieldByName(´COMPOSICAO´).AsString)
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
For I := 1 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Begin
Temp := Temp + Texto[I];
If I = Length(Texto) then
Begin
X[J-1] := Trim(Temp);
SetLength(X, J);
End;
End
Else
Begin
X[J-1] := Trim(Temp);
J := J + 1;
SetLength(X, J);
Temp := ´´;
End;
End;
Temp := ´´;
With Table1 do
Begin
If Locate(´PRODUTO´,Edit2.Text,[]) then
Texto := Trim(FieldByName(´COMPOSICAO´).AsString)
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
J := 1;
For I := 1 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Begin
Temp := Temp + Texto[I];
If I = Length(Texto) then
Begin
Y[J-1] := Trim(Temp);
SetLength(Y, J);
End;
End
Else
Begin
Y[J-1] := Trim(Temp);
J := J + 1;
SetLength(Y, J);
Temp := ´´;
End;
End;
TamanhoX := Length(X);
TamanhoY := Length(Y);
K := 0;
SetLength(Z, TamanhoX * TamanhoY);
For I := 0 to TamanhoX - 1 do
Begin
For J := 0 to TamanhoY - 1 do
Begin
Z[K] := X[I] + ´+´ + Y[J] +´= ´;
K := K + 1;
End;
End;
K := 0;
For I := 0 to TamanhoX - 1 do
Begin
For J := 0 to TamanhoY - 1 do
Begin
Query1.Close;
Query1.SQL.Clear;
Query1.Sql.Add(´Select * From Reacao´);
Query1.Sql.Add(´Where (ELEMENTO1 = :Comp1 And ELEMENTO2 = :Comp2) ´);
Query1.Sql.Add(´Or (ELEMENTO1 = :Comp2 And ELEMENTO2 = :Comp1)´);
Query1.ParamByName(´Comp1´).AsString := X[I];
Query1.ParamByName(´Comp2´).AsString := Y[J];
Query1.Prepare;
Query1.Open;
If Query1.FieldByName(´RESULTADO´).AsString <> ´´ then
Z[K] := Z[K] + Query1.FieldByName(´RESULTADO´).AsString
Else
Z[K] := Z[K] + ´Sem Reação Conhecida´;
K := K + 1;
End;
End;
For I := 0 to High(Z) do
Memo1.Lines.Add(Z[I]);
end;

pode testar a minha que funciona, agora vou testar a sua


Responder

05/02/2006

Edilcimar

Marcos, não entendi este procedimento
procedure CriarMatriz(var B:A;var tamanho:integer;Composicao:String);
o que significa var B:A ?


Responder

05/02/2006

Edilcimar

descobri, a é um array of string; mas vc deu um tamanho de Z = 100, ele pode ser 1 ou 1000, eu não tenho nem idéia inicialmente


Responder

05/02/2006

Marco Salles

Marcos, não entendi este procedimento procedure CriarMatriz(var B:A;var tamanho:integer;Composicao:String); o que significa var B:A ?


descobri, a é um array of string; mas vc deu um tamanho de Z = 100, ele pode ser 1 ou 1000, eu não tenho nem idéia inicialmente


não na verdade eu dei porque voce me explicou assim...

Lembra da minha dúvida em post passados como definir Array Dinamicos

Citação de marcos Pagina 2
beleza.. eu so não to lembrando como se cria uma matriz dinamica


Citacao de Edicilmar Pagina3
Var X : array of string; begin . setlength(x, 100), veja lá em cima onde coloquei em negrito


Mas agora to vendo que o negoci o pode ser este

setlength(x, i); a cada lopp .. Vou testar com esta instrução


Responder

05/02/2006

Marco Salles

Corrigido e Funcionou

procedure CriarMatriz(var B:A;var tamanho:integer;Composicao:String);
var
i,indiceanterior,q:integer;
texto:String;
begin
tamanho:=0;
i:=0;
indiceAnterior:=1;
q:=0;
while i <= (length(composicao)-1) do
 begin
    if composicao[i]=´;´ then
      begin
        texto:=copy(composicao,indiceanterior,i - indiceAnterior);
        tamanho:=Tamanho+1;
        setlength(B,tamanho); //******corrigido
        B[q]:=Trim(texto);
        indiceAnterior:=i+1;
        q:=q+1;
      end;
    i:=i+1;
 end;
if length(composicao) > 0 then
  begin
    if composicao[i]=´;´ then
      texto:=copy(composicao,indiceanterior,i-indiceAnterior)
    else
      texto:=copy(composicao,indiceanterior,(i+1) - indiceAnterior);
    tamanho:=Tamanho+1;
    setlength(B,tamanho); //*********corrigido
    B[q]:=Trim(texto);
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
i,j,indice:integer;
begin
Query1.Close;
Query1.SQL.Clear;
Query1.Sql.Add(´Select *From  Tabela1´);
Query1.Sql.Add(´Where Produto=:NomePrimeiroProduto´);
Query1.ParamByName(´NomePrimeiroProduto´).asstring:=edit1.text;
Query1.Sql.Add(´OR Produto=:NomesegundoProduto´);
Query1.ParamByName(´NomesegundoProduto´).asstring:=edit2.text;
Query1.Prepare;
Query1.open;
if query1.RecordCount = 2 then
  begin
   CriarMatriz(X,tamanhox,query1.FieldByName(´Composicao´).asstring);
   Query1.Next;
   CriarMatriz(y,tamanhoy,query1.FieldByName(´Composicao´).asstring);
   indice:=0;
   for i:=0 to tamanhox-1 do
    begin
      for j:=0 to tamanhoy-1 do
        begin
          Query1.Close;
          Query1.SQL.Clear;
          Query1.Sql.Add(´Select *From  Tabela2´);
          Query1.Sql.Add(´Where ((Composicao1=:Comp1)and(Composicao2=:Comp2))or((Composicao1=:Comp2)and(Composicao2=:Comp1))´);
          Query1.ParamByName(´Comp1´).asstring:=X[i];
          Query1.ParamByName(´Comp2´).asstring:=Y[J];
          Query1.Prepare;
          Query1.open;
          setlength(Z,indice+1);  //******corrigido 
          Z[indice]:=X[i]+´  ´+Y[J];
          if query1.fieldByName(´Reacao´).AsString <> ´´ Then
             Z[Indice]:=Z[Indice]+´  ´+query1.fieldByName(´Reacao´).AsString
          //nada foi encontrado
          else
            Z[indice]:=Z[Indice]+´ Sem Reação Conhecida´;
          Indice:=indice+1;
        end;
   end;
  for i:=0 to indice-1 do //********corrigido
    memo1.Lines.Add(Z[i]);
 end
else
 showmessage(´Pesquisa concluida . Nada fora encontrado´);
end;



Responder

05/02/2006

Edilcimar

ok vou testar


Responder

05/02/2006

Marco Salles

Fiz um teste com a seguinte situação

Tabela 1 ; tabela2

Ver como esta a base de dados da Tabela 1 e da Tabela2

[URL=http://imageshack.us][img:c69ddf97c1]http://img392.imageshack.us/img392/8950/imagemparaedicilmar32kf.jpg[/img:c69ddf97c1][/URL]

Executei agora od dosi métodos ... Button1(Marco) o método que lhe passei , Button2(Edicilmar) o método que me passou

Execução do Button1(Marco).. O resultado no Memo1 Foi este ;

[URL=http://imageshack.us][img:c69ddf97c1]http://img99.imageshack.us/img99/9528/imagemparaedicilmar45ny.jpg[/img:c69ddf97c1][/URL]

Execução do Button2(Edicilmar).. O resultado fo ieste ;

[URL=http://imageshack.us][img:c69ddf97c1]http://img353.imageshack.us/img353/934/imagemparaedicilmar52fr.jpg[/img:c69ddf97c1][/URL]

Não to entendendo porque da diferença ????


Responder

05/02/2006

Edilcimar

Execução do Button1(Marco).. O resultado no Memo1 Foi este ;



Execução do Button2(Edicilmar).. O resultado fo ieste ;



Não to entendendo porque da diferença ????

O que deveria haver entre estas 2 linhas? está em branco


Responder

05/02/2006

Marco Salles

O que deveria haver entre estas 2 linhas? está em branco


Deveria ter os desenhos que gerei a partir da execução do programa... Usei o ImageShack para cria-los .. Consegue ver agora ????


Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar