GARANTIR DESCONTO

Fórum Nao acho a solucao para erro de chave primaria #263776

29/12/2004

0

Olá amigos, tenho a seguinte função para gravar um pedido, quando tento atualizá-lo, dá erro de chave primária:

procedure TfVendas.SalvaPedido(Sender: TObject);
var
   Trs: Ttransactiondesc;
   StringSQL: string;
begin

   try

      if vCodPedido = 0 then
         begin
            DM.SQL_Vendas.Close ;
            DM.SQL_Vendas.CommandText := ´SELECT Max(Pedido) as ProxCod FROM Vendas WHERE CodEmp=:vCodEmp´ ;
            DM.SQL_Vendas.ParamByName(´vCodEmp´).AsInteger := fMenu.CodEmpSelec ;
            DM.SQL_Vendas.Open ;
            EditCodigo.Text := IntToStr(DM.SQL_Vendas.FieldByName(´ProxCod´).asInteger + 1);
            vCodPedido:=uFuncoes.TransInteiro(EditCodigo.Text);
         end;

      DM.SQL_Vendas.Close ;
      DM.SQL_Vendas.CommandText := ´SELECT * FROM Vendas WHERE CodEmp=:vCodEmp AND Pedido=:vPedido´ ;
      DM.SQL_Vendas.ParamByName(´vCodEmp´).AsInteger := fMenu.CodEmpSelec ;
      DM.SQL_Vendas.ParamByName(´vPedido´).AsInteger := vCodPedido ;
      DM.SQL_Vendas.Open ;
      DM.CDS_Vendas.Refresh ;

      if DM.SQL_Vendas.eof then                       {registro não existe}
         begin
            StringSQL := ´INSERT INTO Vendas (CodEmp,Pedido,Data,CodCli,CodPla,TotalBru,TotalLiq) values (:vCodEmp,:vPedido,:vData,:vCodCli,:vCodPla,:vTotalBru,:vTotalLiq)´;
         end
      else
         begin
            StringSQL := ´UPDATE Vendas SET CodEmp=:vCodEmp,Pedido=:vPedido,Data=:vData,CodCli=:vCodCli,CodPla=:vCodPla,TotalBru=:vTotalBru,TotalLiq=:vTotalLiq´;
      end;

      Trs.TransactionID  := 1;
      Trs.IsolationLevel := xilReadCommitted;
      DM.Conexao.StartTransaction(Trs);
      DM.SQL_Vendas.Close ;
      DM.SQL_Vendas.CommandText := StringSQL;
      DM.SQL_Vendas.ParamByName(´vCodEmp´).AsInteger    := fMenu.CodEmpSelec ;
      DM.SQL_Vendas.ParamByName(´vPedido´).AsInteger    := vCodPedido ;
      DM.SQL_Vendas.ParamByName(´vData´).AsDate         := StrToDate(EditData.Text) ;
      DM.SQL_Vendas.ParamByName(´vCodCli´).AsInteger    := uFuncoes.TransInteiro(EditCodCli.Text) ;
      DM.SQL_Vendas.ParamByName(´vCodPla´).AsInteger    := uFuncoes.TransInteiro(EditCodPla.Text) ;
      DM.SQL_Vendas.ParamByName(´vTotalBru´).AsCurrency := EditBruto.Value;
      DM.SQL_Vendas.ParamByName(´vTotalLiq´).AsCurrency := EditLiquido.Value;
      DM.SQL_Vendas.ExecSQL;
      DM.Conexao.Commit(Trs);

      BotaoFimVenda.Enabled := True;
      BotaoCancVenda.Enabled:= True;
      BotaoFechar.Enabled   := False;

   except

      DM.Conexao.RollBack(Trs);
      Application.MessageBox(´Erro ao gravar! Repita a operação´, ´Siga´,MB_OK+MB_ICONINFORMATION);

   end;

end;


No arquivo de vendas, há somente a chave primária criada, assim:

constraint IP_Vendas primary key (codemp,pedido));


Utilizo delphi7,firebird e dbexpress

Um abraço

Mario


Aldus

Aldus

Responder

Posts

29/12/2004

Martins

No seu código tem essa linha:
 StringSQL := ´UPDATE Vendas SET CodEmp=:vCodEmp,Pedido=:vPedido,Data=:vData,CodCli=:vCodCli,CodPla=:vCodPla,TotalBru=:vTotalBru,TotalLiq=:vTotalLiq´;

Acho q se vc colocasse um Where ficaria bom.

vejamos
 StringSQL := ´UPDATE Vendas SET Data=:vData,CodCli=:vCodCli,CodPla=:vCodPla,TotalBru=:vTotalBru,TotalLiq=:vTotalLiq WHERE CodEmp=:vCodEmp AND Pedido=:vPedido´;


Não fis nenhum teste.

Espero q possa lhe ajudar!

Martins


Responder

Gostei + 0

30/12/2004

Vinicius2k

Acho q se vc colocasse um Where ficaria bom.
StringSQL := ´UPDATE Vendas SET Data=:vData, CodCli=:vCodCli, CodPla=:vCodPla, TotalBru=:vTotalBru, TotalLiq=:vTotalLiq WHERE CodEmp=:vCodEmp AND Pedido=:vPedido´;


Colega,

É como o Martins disse mas, na verdade, vc TEM que colocar o where no UPDATE caso contrário a query irá tentar atualizar TODOS os registros com os dados que vc estiver informando nos parametros, por isto o problema da chave primária... a query ´não sabe´ que só deve atualizar um registro específico, se vc não informar qual.

T+


Responder

Gostei + 0

30/12/2004

Aldus

Bom Dia Martins e Vinicius, vocês sabem como é nossa cabeça, as vezes pelo acúmulo de trabalho cometemos erros gritantes, ontem estava produzindo fantasticamente, mas como já era tarde, esbarrei em algo banal, quando li a resposta de vocês, também não precisei testar pra saber o que tinha esquecido.

Um grande abraço pra vocês, e que tenham um ano novo cheio de saúde e união, pois tendo esses fatores, terão sucesso e alegrias.

Até ano que vem...

Mario


Responder

Gostei + 0

31/12/2004

Placido

Bom dia amigo!
Estive anlisando a sua Query, observei que você está usando a função Max() para fazer a incrementação do número do pedido, isto é um risco muito grande quando a sua tabela tem muitos itens este comando pode degradar a sua aplicação, você imagina vários terminais fazendo inserção de pedido e cada inserção você executar a função max()..
Acho temeroso..
Espero ter ajudado.
Um abraço.

Plácido


Responder

Gostei + 0

31/12/2004

Aldus

Bom dia Plácido, como iniciante, fico feliz em ser alertado sobre esses problemas, o que seria mais conveniente? Criar uma tabela que guarda-se esse número sequencial?

Na venda eu uso assim: O usuário entrada na tela de vendas e a partir do lançamento do primeiro item, eu pego o número do pedido, poderia incrementar um nesse contador, e estaria tudo correto. Sé que se o usuário aborta-se o pedido, esse número ficaria perdido.

O que você me sugere?

Aproveitando o tópico, eu havia acessado para inserir uma pergunta: criei no meu clientdataset um campo lookup como sendo nome do cliente na tabela vendas, como faço o select para juntar a tabela vendas e os clientes referentes aos pedidos? Poderia exemplificar?

Ficar a + ou - assim?

Select Vendas.*,Clientes.NomCli FROM Vendas Inner Join Clientes ON (Vendas.CodCli = Clientes.CodCli) WHERE CodEmp=:vCodEmp AND Pedido=:vPedido´ ;

Aproveito para desejar-lhe um ano cheio de saúde e união, base para vida feliz e de sucesso.

Um abraço

Mario


Responder

Gostei + 0

03/01/2005

Cafosys

Para criar código em sequencia você pode usar os geradores do firebird pois estes são o mais seguros.


Responder

Gostei + 0

03/01/2005

Martins

Com certeza o uso de generators é bem mais seguro, e não irá comprometer a performance de sua aplicação.



Martins


Responder

Gostei + 0

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

Aceitar