Erro ao gravar no banco de dados

Delphi

10/05/2014

Boa Tarde amigos, estou com um problema ultimamente eu me deparei com o seguinte problema, ao tentar alterar os dados de uma tabela me da erro de: Column Unknow NOME
uso SqlConnection->SqlQuery->ClientDataset->DataSource->DataSetProvider
na string da sqlquery abro o banco de dados de ORDEM DE SERVICO e pego o campo NOME de uma outra tabela de CLIENTES, ao tentar alterar uso o seguinte:
if(dm.cdsOs.State <> dsInsert) or (dm.cdsOs.State <> dsEdit) then
dm.cdsOs.Edit;
dm.cdsOs.FieldByName('OS_VALOR').AsFloat:=StrToFloat(edtValor.Text);
dm.cdsOs.Post;
dm.cdsOs.ApplyUpdates(1);
end;
Valdson Silva

Valdson Silva

Curtidas 0

Respostas

Felippe Tadeu

Felippe Tadeu

10/05/2014

Boa noite, pode ser que tenha algo de errado no sql da query, tente deletar os campos dessa query e adicionar eles de novo, o mesmo serve pro cds, pode ser que tenha tido alguma alteração nas tabelas e elas ainda não tenham sido alteradas no delphi.

Outra coisa é que esse campo unknown pode estar se referenciando a alguma outra tabela que realmente não tenha.

O ideal seria vc estar postando o código para poder te ajudar, pq sem ele seria apenas chutômetro
GOSTEI 0
Valdson Silva

Valdson Silva

10/05/2014

Bom dia - Alaplaia, obrigado pela força, então como você disse estarei postando o código fonte todo.
Acontece que se eu eliminar o campo NOME que puxei da tabela de clientes o erro não ocorre e grava normalmente.
Abaixo o código que esta na SQLQUERY
-----------------------------------------------------------------------------------------------------
SELECT A.*, B.NOME
FROM OS A, CLIENTES B
WHERE A.OS_CLIENTE = B.ID_CLIENTE
ORDER BY A.OS_NUMERO

Obs: O erro também não ocorre quando uso APPEND, e somente quando vou alterar dados:
GOSTEI 0
Felippe Tadeu

Felippe Tadeu

10/05/2014

Cara,tenho a impressão que é por causa do SQL, o pq de achar isso é que não dá para se fazer um update com mais de uma tabela envolvida, o que daria é se no ClientDataSet estivesse os campos de apenas uma tabela como Data e o resto diferente, pq ao fazer qualquer tipo de alteração no banco o ClientDataSet vai tentar fazer com todos os tipos Data.

Tente fazer a seguinte alteração:

1º No SQL utilize somente uma tabela para OS.

2º Se você usa uma outra Query somente para Clientes, caso não tente criar uma e seguir os passos, adicione no ClientDataSet da OS um campo lookup com as propriedades:
KEY Field = OS_Cliente
Data Set = Data set do cliente
Lookup Keys = id_Cliente
Result Field = nome

Continue usando sem o append para testar.
GOSTEI 0
Felippe Tadeu

Felippe Tadeu

10/05/2014

Uma opinião.. vc usa um TEdit para receber o valor e converte o dado, não ajudaria vc se no ClientDataSet vc usasse um TDBEdit e na propriedade Currency do campo colocar True ?
GOSTEI 0
Valdson Silva

Valdson Silva

10/05/2014

Obg. vou tentar fazer isso!!! valeu
GOSTEI 0
Valdson Silva

Valdson Silva

10/05/2014

Boa Noite
Então consegui uma solução com a seguinte instrução SQL

if(btnAlterar.Caption='Alterar Dados') then
dm.qryOs.Close;
dm.qryOs.SQL.Clear;
dm.qryOs.SQL.Add('Update Os Set Os_Valor=:nVar0');
dm.qryOs.SQL.Add('Where Os_Numero='+dm.cdsOsOS_NUMERO');
dm.qryOs.Params[0].AsFloat := StrToFloat(edtValor.Text);
dm.qryOs.ExecSQL;
end;

* Grava os dados - porém da mensagem de que o Cursor Não Retornou a Qry
qryOs - Cursor not returned from query?????????
GOSTEI 0
Valdson Silva

Valdson Silva

10/05/2014

Boa Noite
Então consegui uma solução com a seguinte instrução SQL

if(btnAlterar.Caption='Alterar Dados') then
dm.qryOs.Close;
dm.qryOs.SQL.Clear;
dm.qryOs.SQL.Add('Update Os Set Os_Valor=:nVar0');
dm.qryOs.SQL.Add('Where Os_Numero=' + IntToStr(dm.cdsOsOS_NUMERO.AsInteger));
dm.qryOs.Params[0].AsFloat := StrToFloat(edtValor.Text);
dm.qryOs.ExecSQL;
end;

* Grava os dados - porém da mensagem de que o Cursor Não Retornou a Qry
qryOs - Cursor not returned from query?????????
GOSTEI 0
Felippe Tadeu

Felippe Tadeu

10/05/2014

Hmm.. essa vou ficar devendo, mas vou dar uma pesquisada, mas se for urgente faça como falei, desse jeito tenho certeza que dará certo.
GOSTEI 0
Valdson Silva

Valdson Silva

10/05/2014

Thanks.
GOSTEI 0
Andreas Aquino

Andreas Aquino

10/05/2014

Bom dia Valdson!

Para utilizar o ClientDataSet com SQL-SELECT's que retornam dados de mais de uma tabela (joins) você deverá alterar a propriedade ProviderFlags dos campos da tabela relacionada, no seu caso seria do campo "NOME", deixando todas as opções como False (pfInUpdate, pfInWhere, pfInKey, pfHidden) neste caso o ClientDataSet conseguirá aplicar a atualização na tabela principal. O inconveniente é que no caso de inserção dos dados via DbGrid, o nome do cliente não será retornado automaticamente, você terá que atualizar este manualmente, ou então abrir e fechar o CDS para que os dados sejam lidos novamente do BD.

Atenciosamente,

Andreas
GOSTEI 0
Felippe Tadeu

Felippe Tadeu

10/05/2014

Andreas, bom dia.

Mas se fosse um lookupfield no ClientDataSet iria atualizar automaticamente
GOSTEI 0
Valdson Silva

Valdson Silva

10/05/2014

Valeu obrigadão
GOSTEI 0
Andreas Aquino

Andreas Aquino

10/05/2014

Realmente Alaplaia, trabalhando com o carregamento dos Fields no CDS esta situação é resolvida com o Lookup Field. Eu procuro não trabalhar desta forma. Abraço.
GOSTEI 0
Felippe Tadeu

Felippe Tadeu

10/05/2014

Mas funciona apenas tirando os flags funciona, vou testar assim que der.

Como vc faz nesses casos ?
GOSTEI 0
Wilton Júnior

Wilton Júnior

10/05/2014

Vanderson aqui no dm.cdsOs.ApplyUpdates(1) eu faço coloco assim dm.cdsOs.ApplyUpdates(-1);
Tenta e ve o que da.
GOSTEI 0
POSTAR