Ir para conteúdo
Fórum Script Brasil
  • 0

Erro ao salvar


ZueRa

Pergunta

Boa noite!

Estou tendo um problema ao salvar um registro em meu bd. Estou usando Query + UpdateSQL.

O erro é o seguinte: abro um registro, seleciono o que quero modificar, modifico e, ao clicar em salvar aparece a mensagem (Type mismatch in expression .'.).

Porém não consigo achar onde possa estar errado, alguém poderia me ajudar?

Seção do código para salvar

procedure TFaddobs.SpeedButton2Click(Sender: TObject);
var
pw_ansichar_add : PAnsiChar;
l_receive : string;
  begin
    if (Dmdados.Qaddobs.State in [dsInactive]) then
      begin
        Application.MessageBox('Primeiro adicione um novo registro para ser salvo.','Goldner',MB_ok +
        MB_defbutton1 + MB_iconexclamation);
        Abort;
      end;
    Dmdados.Qaddobs.Active := true;
    Dmdados.Qaddobs.ApplyUpdates; //também já tentei o ApplyUpdates em baixo do Post
    Dmdados.Qaddobs.Post;
    //Dmdados.UpdateSQL2.DataSet.Post;
    //Dmdados.Qaddobs.ApplyUpdates;
    DBEdit1.Text := Fprogram.DBEdit1.Text;
    l_receive := DBEdit1.Text;
    pw_ansichar_add := PAnsiChar('Registro salvo com sucesso! Código: ('+ l_receive +')');
    Application.MessageBox(pw_ansichar_add,'Goldner',MB_ok +
    MB_defbutton1 + MB_iconexclamation);
    //Dmdados.Qaddobs.Close;
    //Dmdados.UpdateSQL1.DataSet.Post;
    BlockButtons;

Desde já agradeço,

Thiago.

Link para o comentário
Compartilhar em outros sites

12 respostass a esta questão

Posts Recomendados

  • 0

Zuera, o código aparentemente não mostra nada que possa ajudar na compreensão do seu problema.

O erro deve ser proveniente de alguma das instruções SQL que você usa no UpdateSQL2. Acredito que seria interessante você postar estes SQL para avaliação.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Olá Micheus, bom dia.

O código para o UpdateSQL2 está assim:

Modify

update cfgc
set
  Codigo = :Codigo,
  Dtregistro = :Dtregistro,
  Obsregistro = :Obsregistro,
  Obsstatus = :Obsstatus
where
  Codigo = :OLD_Codigo and
  Dtregistro = :OLD_Dtregistro and
  Obsregistro = :OLD_Obsregistro and
  Obsstatus = :OLD_Obsstatus
Insert
insert into cfgc
  (Codigo, Dtregistro, Obsregistro, Obsstatus)
values
  (:Codigo, :Dtregistro, :Obsregistro, :Obsstatus)
Delete
delete from cfgc
where
  Codigo = :OLD_Codigo and
  Dtregistro = :OLD_Dtregistro and
  Obsregistro = :OLD_Obsregistro and
  Obsstatus = :OLD_Obsstatus

Só uma observação: deixei de gerar o código SQL para os campos com (*) na tabela.

Grande abraço.

Editado por ZueRa
Link para o comentário
Compartilhar em outros sites

  • 0

Por acaso, desde que você colocou estes componentes no seu form/datamodule, você fez alguma alteração na estrutura da tabela em questão? Alterou o tipo de dados ou tamanho de algum campo? Os parâmetros estão devidamente configurados quanto ao seu tipo?

Olhando o código, tem algo estranho nesta parte:

...
    Dmdados.Qaddobs.Active := true;
    Dmdados.Qaddobs.ApplyUpdates; //também já tentei o ApplyUpdates em baixo do Post
    Dmdados.Qaddobs.Post;

como é que você ativa o dataset e sem inicializar seus valores, usa o ApplayUpdates e Post? Quando é que os campos/parâmetros estão sendo inicializados?

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
Por acaso, desde que você colocou estes componentes no seu form/datamodule, você fez alguma alteração na estrutura da tabela em questão? Alterou o tipo de dados ou tamanho de algum campo? Os parâmetros estão devidamente configurados quanto ao seu tipo?

Olhando o código, tem algo estranho nesta parte:

...
    Dmdados.Qaddobs.Active := true;
    Dmdados.Qaddobs.ApplyUpdates; //também já tentei o ApplyUpdates em baixo do Post
    Dmdados.Qaddobs.Post;

como é que você ativa o dataset e sem inicializar seus valores, usa o ApplayUpdates e Post? Quando é que os campos/parâmetros estão sendo inicializados?

Abraços

Não entendi Micheus.

Mas, acho que os campos/parâmetros não estão sendo inicializados.

Link para o comentário
Compartilhar em outros sites

  • 0

ZueRa, não estou conseguindo pensar em uma forma de lhe ajudar com isso. Eu não costumo usar UpdateSQL - espero que algum outro colega possa lhe dar uma luz.

E quanto a questão "Olhando o código, tem algo estranho nesta parte..."? Olhou isto?

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
ZueRa, não estou conseguindo pensar em uma forma de lhe ajudar com isso. Eu não costumo usar UpdateSQL - espero que algum outro colega possa lhe dar uma luz.

E quanto a questão "Olhando o código, tem algo estranho nesta parte..."? Olhou isto?

Abraços

Olá Micheus.

Veja bem, só estou usando o UpdateSQL pelo fato de que quanto eu ia colocar a tabela no modo de Edição aparecia aquele errinho típico: "Cannot modify a read-only TDataSet" (algo assim). Mesmo que o RequestLive da Query estivesse como true, mostrava isto.

Não achei outra solução e o código estava certinho (imagino eu).

Se você achar que tem outra solução além do UpdateSQL, ou para parar de mostrar esta mensagem, seria de grande ajuda.

Abraço.

Link para o comentário
Compartilhar em outros sites

  • 0

Só adicionando:

acho que aparecia este erro (cannot modify...) por ser executado este código:

Dmdados.Qaddobs.SQL.Text := 'select * from cfg as c, cfgc as f where f.Codigo ='+ QuotedStr(Edconsobs.Text) +' and c.Nfunc ='+ QuotedStr(Fprogram.DBEdit2.Text);

ou seja, estou fazendo referência a duas tabelas.

Se não me engano este tipo de consulta deixa o DataSet em ReadOnlye = ture. Porém, mesmo após a consulta colocando o RequestLive = true entre outros, dá na mesma.

Talvez na hora de editar há como resolver isto sem a ajuda do SQL Update e, sem aparecer este erro, claro.

Editado por ZueRa
Link para o comentário
Compartilhar em outros sites

  • 0

Zuera, vamos ver se com o que postei abaixo, você consegue resolver seu problema - ficou muito grande, então leia com calma. Espero que esteja correto. :D

Quanto a esta sua observação, ela está correta: vai ficar read-only sim. (nada como um pouco mais de informação ;))

Por esta última fração de código, dá para ver que teria que dar algum erro de qualquer jeito - se o dataset QAddObs tem este select composto, e você sabe que não pode modificar seus dados.

Aparentemente voce não inicializa mesmo os parâmetros em lugar algum.

Isto tem que ser feito, já que você tem 3 opções (SQL) de manipulação da tabela através do componente TUpdateSQL. Conforme a ação que você esteja fazendo, deverá utilizar uma das opções como parâmetro para a ação:

- ukModify (quando alterando)

- ukInsert (quando adicionando)

- ukDelete (quando excluindo)

Estive olhando e, em design-time, o componente TUpdateSQL não há uma propriedade DataSet para indicar o dataset de onde virão os dados para os parâmetros (quando eles existem), mas no help há indicação de que a propriedade existe. Talvez ela seja inicializada quando você selecina manipula a propriedade UpdateSQL do dataset "read-only".

Se isto estiver correto (e acho que deve estar), para você inicializar os parâmetros e executar a operação desejada basta que você use o método Applay do componente TUpdateSQL:

ex.: UpdateSQL1.Applay(ukModify);

Qualquer parâmetro que não venha do dataset, pode ser incializado usando o método ParamByName:

ex. UpdateSQL1.ModifySQL.ParamByName('DatAtualizacao').Value = Now;

Com isto, o problema deveria "sumir".

Mas, caso isto não ocorra ou você estivesse fazendo tudo no código, uma alternativa é iniciar a propriedade DataSet em run-time:

ex. UpdataSQL1.DataSet := QAddObs; (definindo o dataset de origem dos valores para os parâmetros)

Conforme a ação que você esteja fazendo, deverá utilizar uma das opções para inicializar os parâmetros adequados através do método SetParams do componente TUpdateSQL:

ex. UpdataSQL1.SetParams(ukModify);

Depois para que o comando desejado seja executado, você pode usar o método ExecSQL ou Applay, para que o respectivo comando seja executado usando os parâmetros inicializados com o método já citado:

ex.: UpdataSQL1.ExecSQL(ukModify);

Observe, ainda, que você deve ter habilitado no seu dataset "read-only" a propriedade CachedUpdates antes de usar este recurso do TUpdateSQL. Como vê, você estará manipulando este componente - não o dataset em si.

Um documento interessante, que pode ser usado como referência porque mesmo tratando de componentes da paleta IB, grande parte da funcionalidade diz respeito à classe comum entre estes componentes TDataSet: Interbase Developer Guide (em Inglês - ref. Unicamp) - este assunto é tratado na seção Working with Cached Updates.

Abraços

Editado por Micheus
Link para o comentário
Compartilhar em outros sites

  • 0

Posso dar uma opnião?

quando vou salvar algo em ExecQuery faço o seguinte: crio uma query para execução de sql's pode ser uma IBQuery, IBSQL ou outro. OBS(pode mudar as propriedades usadas de uma para outra);

//use uma query instanciada e não a que está aberta. crie um novo objeto.
Try Try
with dm, nomequery_instanciada, SQL, ibtrans do begin //dm > datamodule, ibtrans > ibtransaction, SQL > propriedade da query, repare que componentes e propriedades são separados por " , " um componente que tenha as mesmas propriedades identicas não podem estar no mesmo with
  if active then close; //se usar uma que já está aberta, ele fecha;
  Text:='insert into tb (campos.....) values (:p1,:p2......)'; //text subpropriedade da query em SQL."text" que está no with
  ParamByName('p1').AsString := Edit1.Text;
  Para...
  ...
  ExecQuery; //depende do componente (IBQuery, IBSQL ou IBDataset...) a ser usado
  CommitRataining;
  //depois disso atualize o conteudo da que está aberta. para recuperar os valores postados em commitra...
end;
Except on Exception do 
  showmessage('Houve um erro ao salvar o registro.');
end;
Finally
  showmessage('O registro foi salvo com sucesso codigo: '+...);
end;
Bom! A respeito disso, acho que não funciona legal, por que você está abrindo a consulta com o active := true, lhe aconselho a usar um execute ao invés disso.
Dmdados.Qaddobs.Active := true;
    Dmdados.Qaddobs.ApplyUpdates; //também já tentei o ApplyUpdates em baixo do Post
    Dmdados.Qaddobs.Post;

O exemplo que citei eu uso para o FB/IB mais com certeza tem algo para ADOConn e outros ADOComponents.

Agora a mensagem que ele retorna (Type mismatch in expression) pode ser em uma clausula sql usada erradamente.

Se você for usar o ApplyUpdates não use o Post se for usar o Post não use o ApplyUpdates os dois tem a mesma função, depois de usar " um " dos dois comite os dados usando o CommitRataining "dados retidos" não fechando assim sua transação com a base.

No exemplo acima não usei o applyupdate nem o post, executei direto para o banco a partir do objeto qry, não esqueça de que ao instanciar uma qry local de setar o database do mesmo.

qry.database := dm.dbconn; //entendeu

espero ter ajudado um pouco.

té mais!!!

Link para o comentário
Compartilhar em outros sites

  • 0

Novamente venho lembrar que é muito importante que os componentes em uso sejam corretamente citados.

Considerando que o colega Zuera esteja usando o componente TUpdateSQL, constante da paleta BDE, então os outros componentes utilizados podem ter sido: conexão com banco de dados TDataBase e consultas SQL via TQuery.

Assim, fugindo um pouco do foco, só para não gerar qualquer confusão para algum leitor distraído, caso os componentes em uso sejam mesmo estes citados...

quando vou salvar algo em ExecQuery faço o seguinte: crio uma query para execução de sql's pode ser uma IBQuery, IBSQL ou outro. OBS(pode mudar as propriedades usadas de uma para outra);
apenas chamando a atenção para o fato de que o método ExecQuery é exclusivo do componente TIBSQL (não descendente da classe TDataSet). Os demais componentes, como TQuery (possivelmente usado pelo colega Zuera), TSQLDataSet, TSQLQuery, TUpdateSQL, TADOQuery, TIBDataSet, TIBQuery, TIBUpdateSQL e tantos outros usam o ExecSQL para execução das instruções SQL.

Quando o colega Eder Moraes cita no exemplo CommitRetaining, está referindo-se ao uso de transações. Este é um ponto interessante de ser observado e o importante é procurar entender o conceito (há muitas apostilas que falam a respeito) e este artigo: Programação Cliente/Servidor - parte 4, comenta um pouquinho sobre isso.

Mas, voltando ao exemplo, para que este recurso seja utilizado, em algum ponto do código no processo atual (seja de inclusão, alteração, ...), deve ocorrer o início desta transação. Quando uma transação é iniciada, ela pode ser efetivada (Commit) ou desfeita/cancelada (RollBack).

O help do Delphi tem um exemplo de como isso ocorreria ao utilizar componentes descendentes da classe TBDEDataSet:

procedure TForm1.ApplyButtonClick(Sender: TObject);
begin
  with CustomerQuery do
  begin
  Database1.StartTransaction;
    try
      ApplyUpdates; {try to write the updates to the database};
      Database1.Commit; {on success, commit the changes};
    except
      Database1.Rollback; {on failure, undo the changes};
      raise; {raise the exception to prevent a call to CommitUpdates!}
    end;
    CommitUpdates; {on success, clear the cache}
  end;
end;

Os diversos componentes relacionados a transações tem varições com relação ao nome dos métodos, então é importante buscar na documentação (help ou net), quais os métodos que você poderá utilizar para aplicar este recurso. A título de exemplo:

TIBTransaction (IB), TZConnection (Zeos):

- StartTransaction

- CommitRetaining e Commit

- RollbackRetaining e Rollback

TADOConnection (ADO)

- BeginTrans

- CommitTrans

- RollbackTrans

TDataBase (BDE), TSQLConnection (dbExpress)

- StartTransaction

- Commit

- Rollback

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Olá Micheus, Eder Moraes.

Bom, primeiramente obrigado por ajudar.

Testei aqui de todas as formas possíveis, mas continua dando "type mismatch in expression '.'". Só que, não acho onde isto possa estar acontecendo.

Eder sobre o erro eu sei que é em algum lugar na instrução SQL, porém, ela é gerada automaticamente pelo UpdateSQL. Então ele as gerou erroneamente?

Abraço.

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...