Left Join nao retornou nada
Olá amigos, estou tentando fazer um left join como abaixo:
Após abrir o Client, debugo as variáveis para ver seu conteúdo:
DM.CDS_Vendas.FieldByName(´Pedido´).asstring ---> Traz o valor correto
DM.CDS_Vendas.FieldByName(´CodCli´).asstring ---> Traz o valor correto
Quando debugo a variável NomCli
DM.CDS_Vendas.FieldByName(´NomCli´).asstring ---> Traz o seguinte erro
Aproveitando o tópico, como incluo esse campo no ClientDataSet para acessá-lo no dbGrid? Já que os demais campos da tabela vendas existem fisicamente e já os inclui no DataModule, e esse campo ´Virtual´ NomCli só passou a existir quando da execução dessa Query acima.
O que está errado?
Abraços
Mario
´Select Vendas.*,Clientes.NomCli FROM Vendas Left Join Clientes ON (Vendas.Codcli=Clientes.CodCli) WHERE (Vendas.CodEmp=:vCodEmp and Vendas.CodEmp=Clientes.CodEmp) ORDER BY Vendas.Data+Vendas.Pedido DESC´;
Após abrir o Client, debugo as variáveis para ver seu conteúdo:
DM.CDS_Vendas.FieldByName(´Pedido´).asstring ---> Traz o valor correto
DM.CDS_Vendas.FieldByName(´CodCli´).asstring ---> Traz o valor correto
Quando debugo a variável NomCli
DM.CDS_Vendas.FieldByName(´NomCli´).asstring ---> Traz o seguinte erro
Delphi exception EDatabaseError at $84BF92D
Aproveitando o tópico, como incluo esse campo no ClientDataSet para acessá-lo no dbGrid? Já que os demais campos da tabela vendas existem fisicamente e já os inclui no DataModule, e esse campo ´Virtual´ NomCli só passou a existir quando da execução dessa Query acima.
O que está errado?
Abraços
Mario
Aldus
Curtidas 0
Respostas
Emerson Nascimento
01/02/2005
esteticamente, a instrução ficaria melhor assim:
Select Vendas.*, Clientes.NomCli
FROM Vendas
Left Join Clientes ON (Clientes.CodCli=Vendas.Codcli and Clientes.CodEmp=Vendas.CodEmp)
WHERE Vendas.CodEmp=:vCodEmp
ORDER BY Vendas.Data, Vendas.Pedido DESC
para incluir esse campo no ClientDataset você precisa colocar essa instrução nele e abri-lo em tempo de projeto. Depois você executa os procedimentos normais para inclusão do campo persistente e fecha o ClientDataset.
mas fiquei com um dúvida: porque você tem o campo CodEmp na tabela de clientes?
Select Vendas.*, Clientes.NomCli
FROM Vendas
Left Join Clientes ON (Clientes.CodCli=Vendas.Codcli and Clientes.CodEmp=Vendas.CodEmp)
WHERE Vendas.CodEmp=:vCodEmp
ORDER BY Vendas.Data, Vendas.Pedido DESC
para incluir esse campo no ClientDataset você precisa colocar essa instrução nele e abri-lo em tempo de projeto. Depois você executa os procedimentos normais para inclusão do campo persistente e fecha o ClientDataset.
mas fiquei com um dúvida: porque você tem o campo CodEmp na tabela de clientes?
GOSTEI 0
Aldus
01/02/2005
Olá Emerson, que uso o campo codemp porque estou desenvolvendo para poder trabalhar com multiplas empresas dentro do mesmo banco.
Quanto a sua resposta. Eu estou utilizando apenas um clientdataset para cada tabela, nesses casos que tenho que buscar o conteúdo de outras, seria interessante ter um clientdataset apenas para consulta?
Atenciosamente
Mario
Quanto a sua resposta. Eu estou utilizando apenas um clientdataset para cada tabela, nesses casos que tenho que buscar o conteúdo de outras, seria interessante ter um clientdataset apenas para consulta?
Atenciosamente
Mario
GOSTEI 0
Emerson Nascimento
01/02/2005
você pode ter um cds só para consulta ou pode deixar de trabalhar com campos persistentes, criando as colunas de cada grid ´na mão´.
GOSTEI 0
Emerson Nascimento
01/02/2005
quanto ao multi-empresas, é multi-empresas ou multi-filiais?
porque creio que o correto seria ter um banco de dados para cada empresa, e dentro desse banco apontar as filiais. pois supõe-se que todas as filiais tenham o mesmo foco, tanto em clientes quanto em produtos. o que não é necessariamente verdadeiro em se tratando de empresas diferentes.
mesmo porque isso garantiria o bom gerenciamento dos dados, tanto em performance quanto em segurança.
imagine que você tem dados de três empresas distintas num mesmo banco de dados. se por acaso esse banco de dados sofrer algum dano, as três empresas serão prejudicadas (mesmo que momentaneamente), o que não ocorreria se esses dados estivessem distribuídos em três bancos diferentes: apenas uma empresa seria prejudicada.
então, a estrutura deveria ser mais ou menos assim:
porque creio que o correto seria ter um banco de dados para cada empresa, e dentro desse banco apontar as filiais. pois supõe-se que todas as filiais tenham o mesmo foco, tanto em clientes quanto em produtos. o que não é necessariamente verdadeiro em se tratando de empresas diferentes.
mesmo porque isso garantiria o bom gerenciamento dos dados, tanto em performance quanto em segurança.
imagine que você tem dados de três empresas distintas num mesmo banco de dados. se por acaso esse banco de dados sofrer algum dano, as três empresas serão prejudicadas (mesmo que momentaneamente), o que não ocorreria se esses dados estivessem distribuídos em três bancos diferentes: apenas uma empresa seria prejudicada.
então, a estrutura deveria ser mais ou menos assim:
bancoXX (onde XX é o código da empresa) clientes (não me preocupo com a filial) id_cliente cnpjcpf endereco produtos (não me preocupo com a filial) id_produto codigo nome descricao saldos (me preocupo com a filial) id_produto id_local id_filial saldoatual pedidos (me preocupo com a filial) id_pedido id_filial numero data pedidositens (não me preocupo com a filial, pois está embutida no pedido) id_item id_pedido id_produto valorunitario quantidade e assim por diante
GOSTEI 0
Aldus
01/02/2005
Emerson, expressei-me errado, o controle é multi-filiais, mas quanto a isso não tenho problemas.
Eu tenho um form de consulta padrão e já crio os campos manualmente, como abaixo, só que como citei acima, era para o campo ´NomCli´ estar disponível quando debugo após a query, não era?
Até
Eu tenho um form de consulta padrão e já crio os campos manualmente, como abaixo, só que como citei acima, era para o campo ´NomCli´ estar disponível quando debugo após a query, não era?
Lista.DataSource := DM.DS_Vendas ; Lista.Columns.Add; Lista.Columns[0].FieldName := ´PEDIDO´; Lista.Columns[0].Title.Caption:= ´Pedido´; Lista.Columns.Add; Lista.Columns[1].FieldName := ´DATA´; Lista.Columns[1].Title.Caption:= ´Data da Venda´; Lista.Columns.Add; Lista.Columns[2].FieldName := ´CODCLI´; Lista.Columns[2].Title.Caption:= ´Cliente´; Lista.Columns.Add; Lista.Columns[3].FieldName := ´NOMCLI´; Lista.Columns[3].Title.Caption:= ´Nome do Cliente´; Lista.Columns.Add; Lista.Columns[4].FieldName := ´CODPLA´; Lista.Columns[4].Title.Caption:= ´Pagamento´; Lista.Columns.Add; Lista.Columns[5].FieldName := ´TOTALBRU´; Lista.Columns[5].Title.Caption:= ´Total Bruto´; Lista.Columns.Add; Lista.Columns[6].FieldName := ´TOTALLIQ´; Lista.Columns[6].Title.Caption:= ´Total Líquido´;
Até
GOSTEI 0
Emerson Nascimento
01/02/2005
ele só estaria disponível [b:249497d60a]depois de aberta a query[/b:249497d60a] e se [b:249497d60a]não houver campos persistentes[/b:249497d60a].
GOSTEI 0
Aldus
01/02/2005
Emerson, por favor examine esse código, que uso para filtrar todos os pedidos e depois apresentá-los no grid
Após o Open, debugo todos os campos para testar ´dm.cds_vendas.fieldbyname(nomedocampo).asstring´, todos retornam o seu conteúdo, exceto o danado ´NomCli´ que retorna aquele erro ´Delphi exception EDatabaseError at $84BF92D´
O que está errado, a sintaxe da instrução está correta?
Mario
DM.CDS_Vendas.Close ;
DM.SQL_Vendas.CommandText := ´Select Vendas.*,Clientes.NomCli as NomCli
FROM Vendas
Left Join Clientes ON (Vendas.Codcli=Clientes.CodCli)
WHERE (Vendas.CodEmp=:vCodEmp and Vendas.CodEmp=Clientes.CodEmp)
ORDER BY Vendas.Data+Vendas.Pedido DESC´;
DM.SQL_Vendas.ParamByName(´vCodEmp´).AsInteger := fMenu.CodEmpSelec ;
DM.CDS_Vendas.Open ;
Após o Open, debugo todos os campos para testar ´dm.cds_vendas.fieldbyname(nomedocampo).asstring´, todos retornam o seu conteúdo, exceto o danado ´NomCli´ que retorna aquele erro ´Delphi exception EDatabaseError at $84BF92D´
O que está errado, a sintaxe da instrução está correta?
Mario
GOSTEI 0
Paulo_amorim
01/02/2005
Olá
Após abrir, debugue e tente verificar:
Só pra começar, o número de campos que o Cds está retornando. Se for diferente do esperado (o total de campos da tabela vendas + NomCli) pode ser isso
Depois, verifique o nome dos campos (Fields[i].FieldName) , principalmente os últimos. Certifique-se de que o seu campo está lá
Provavelmente o erro está em alguma coisa nesses passos... senão ele traria normalmente...
Até+
Após abrir, debugue e tente verificar:
Só pra começar, o número de campos que o Cds está retornando. Se for diferente do esperado (o total de campos da tabela vendas + NomCli) pode ser isso
Depois, verifique o nome dos campos (Fields[i].FieldName) , principalmente os últimos. Certifique-se de que o seu campo está lá
Provavelmente o erro está em alguma coisa nesses passos... senão ele traria normalmente...
Até+
GOSTEI 0
Emerson Nascimento
01/02/2005
aparentemente não há nada errado, mas estou me perguntando porque não dá erro ao abrir a query, pois você somou o Vendas.Data+Vendas.Pedido, e eu supondo que são campos de tipos diferentes.
como eu disse antes, apenas por estética, eu faria assim:
outra coisa: na tabela Vendas não há um campo [i:940ffb318d]NomCli[/i:940ffb318d], né? Se houver, talvez o sistema esteja se perdendo por não saber qual campo utilizar...
como eu disse antes, apenas por estética, eu faria assim:
with DM.CDS_Vendas do begin Close; CommandText := ´Select Vendas.*, Clientes.NomCli FROM Vendas ´+ ´Left Join Clientes ON (Clientes.CodCli=Vendas.Codcli and Clientes.CodEmp=Vendas.CodEmp) ´+ ´WHERE Vendas.CodEmp=:vCodEmp ´+ ´ORDER BY Vendas.Data, Vendas.Pedido DESC ´; ParamByName(´vCodEmp´).AsInteger := fMenu.CodEmpSelec; Open; end
outra coisa: na tabela Vendas não há um campo [i:940ffb318d]NomCli[/i:940ffb318d], né? Se houver, talvez o sistema esteja se perdendo por não saber qual campo utilizar...
GOSTEI 0
Aldus
01/02/2005
Progresso Emerson. No meu datamodule, estavam incluidos todos campos da tabela vendas, é claro menos o NomCli pois o mesmo não existe. Retirei todos os campos do cds, aí apareceu o nome dos clientes. Só que para formatar os valores por exemplo que aparecerão no grid preciso incluí-los no cds para alterar o displayformat, daí incluo somente estes campos numéricos, daí no resultado da query, só me retorna aqueles campos que estão incluídos.
Daí o dilema, se incluo todos no cds, não aparece o NomCli no grid ou se não incluo nenhum, aparece tudo mas não posso formatar os valores no grid, pois como você viu acima, eu incluo os campos em runtime e não há propriedade para formatá-los.
E agora brother, sabes o que posso fazer?
Daí o dilema, se incluo todos no cds, não aparece o NomCli no grid ou se não incluo nenhum, aparece tudo mas não posso formatar os valores no grid, pois como você viu acima, eu incluo os campos em runtime e não há propriedade para formatá-los.
E agora brother, sabes o que posso fazer?
GOSTEI 0
Emerson Nascimento
01/02/2005
foi o que eu te disse acima você ´pode deixar de trabalhar com campos persistentes´....
você pode, sim, criar as máscaras de formatação em tempo de execução.
por exemplo:
depois de abrir a query:
você pode, sim, criar as máscaras de formatação em tempo de execução.
por exemplo:
depois de abrir a query:
with DM.CDS_Vendas do begin TDateTimeField(FieldByName(´DATA´)).DisplayFormat := ´dd/mm/yyyy´; TFloatField(FieldByName(´TOTALBRU´)).DisplayFormat := ´,#0.00´; TFloatField(FieldByName(´TOTALLIQ´)).DisplayFormat := ´,0.00´; end;
GOSTEI 0
Aldus
01/02/2005
Salve Salve Emerson! Amigo, acho que é essa a solução, apenas quando declaro o display me dá a seguinte mensagem de erro ´[Error] uConsulta.pas(322): Undeclared identifier: ´TFloatField´´. Está faltando declarar algo em uses né?
Aguardo ancioso seu retorno.
Mario
Aguardo ancioso seu retorno.
Mario
GOSTEI 0
Emerson Nascimento
01/02/2005
basta declarar a unit DB na cláusula uses.
GOSTEI 0
Aldus
01/02/2005
Estou tipo trancado pelos pés cara. Quase lá, mas ainda deu o mesmo erro, declarei no uses e ...
unit uConsulta;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, uConsultaPai, StdCtrls, ExtCtrls, Grids, DBGrids, Buttons,
ComCtrls, DB;
GOSTEI 0
Emerson Nascimento
01/02/2005
publique o código exatamente como você fez no Delphi.
GOSTEI 0
Aldus
01/02/2005
No uses:
Instrução:
Até
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, uConsultaPai, StdCtrls, ExtCtrls, Grids, DBGrids, Buttons,
ComCtrls, DB;
Instrução:
fConsulta.Caption := ´Lista de Pedidos´;
DM.CDS_Vendas.Close ;
DM.SQL_Vendas.CommandText := ´Select Vendas.*,Clientes.NomCli as NomCli FROM Vendas Left Join Clientes ON (Vendas.Codcli=Clientes.CodCli) WHERE (Vendas.CodEmp=:vCodEmp and Vendas.CodEmp=Clientes.CodEmp) ORDER BY Vendas.Data+Vendas.Pedido DESC´;
DM.SQL_Vendas.ParamByName(´vCodEmp´).AsInteger := fMenu.CodEmpSelec ;
DM.CDS_Vendas.Open ;
DM.CDS_Vendas.TFloatField(FieldByName(´TOTALBRU´)).DisplayFormat := ´,#0.00´;
DM.CDS_Vendas.TFloatField(FieldByName(´TOTALLIQ´)).DisplayFormat := ´,0.00´;
Até
GOSTEI 0
Emerson Nascimento
01/02/2005
está errado!
o correto é:
TFloatField(DM.CDS_Vendas.FieldByName(´TOTALBRU´)).DisplayFormat := ´,#0.00´;
TFloatField(DM.CDS_Vendas.FieldByName(´TOTALLIQ´)).DisplayFormat := ´,0.00´;
TFloatField é uma classe distinta, e não um método do ClientDataset.
o correto é:
TFloatField(DM.CDS_Vendas.FieldByName(´TOTALBRU´)).DisplayFormat := ´,#0.00´;
TFloatField(DM.CDS_Vendas.FieldByName(´TOTALLIQ´)).DisplayFormat := ´,0.00´;
TFloatField é uma classe distinta, e não um método do ClientDataset.
GOSTEI 0
Aldus
01/02/2005
Poxa Emerson, funcionou tudo uma bleza.
Obrigado pelo tempo e paciência em ter me ajudado.
Com certeza, o que aprendi com você vou repassar a outro amigo delphiano que tiver dificuldade.
Obrigado mesmo cara.
Mario
Obrigado pelo tempo e paciência em ter me ajudado.
Com certeza, o que aprendi com você vou repassar a outro amigo delphiano que tiver dificuldade.
Obrigado mesmo cara.
Mario
GOSTEI 0