[firebase-br] RES: Invalid Cursor

Rodrigo dominio em engeplus.com.br
Ter Set 1 14:40:19 -03 2009


Acho que trigger para o meu sistema não da certo.

Uma pq o valor do Estoque no meu caso é Numeric(8,4), para aceitar no caso 
Kg, que as vezes vende 1.555 gr.
Outro é pq tb tem uma outra variavel Qtd Un. que quando um produto é Caixa 
com 24 entao se o cliente quiser vender uma unidade, o meu sistema calcula o 
EstoqueCx e o EstoqueUn.

Tentei fazer, mas deu varios erros e nao consegui concluir a trigger.

CREATE TRIGGER TR_CALCITENS_BI FOR ITENS
ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 0
AS
DECLARE VARIABLE NOVAQTD INTEGER;
DECLARE VARIABLE DIV1 INTEGER;
DECLARE VARIABLE MOD1 INTEGER;
DECLARE VARIABLE QTDUN INTEGER;
BEGIN
      IF (DELETING) THEN
      UPDATE PRODUTOS SET PRODUTOS.ESTOQUE = PRODUTOS.ESTOQUE +
      ITENS.QTD WHERE PRODUTOS.CODIGO = OLD.CODIGO;

      IF (UPDATING OR INSERTING) THEN BEGIN
      /* aqui se for produtos com unidades iguais */
      if (Itens.Unidade = 'UN' AND PRODUTOS.UNIDADE = 'UN') THEN BEGIN
      UPDATE PRODUTOS SET PRODUTOS.ESTOQUE = PRODUTOS.ESTOQUE -
      NEW.ESTOQUE WHERE PRODUTOS.CODIGO = NEW.CODIGO;
      END
      /* aqui se for produtos com unidades diferentes */
      if (Itens.Unidade <> 'UN' AND PRODUTOS.UNIDADE <> 'UN') THEN BEGIN
      UPDATE PRODUTOS SET PRODUTOS.ESTOQUE = PRODUTOS.ESTOQUE -
      NEW.ESTOQUE WHERE PRODUTOS.CODIGO = NEW.CODIGO;
      END
      /* aqui se precisa de verificação */
      if (Itens.Unidade = 'UN' AND PRODUTOS.UNIDADE = 'UN') THEN BEGIN
      if (Produtos.EstoqueUnd < Itens.Qtd) then begin
      if (Produtos.QTDUN is null or Produtos.QTD = '') then
      QTDUN = 1;
      else
      QTDUN = PRODUTOS.QTDUN;

      NOVAQTD = ((PRODUTOS.ESTOQUE * StrToInt(CurrToStr(QtdUn)) )+ 
PRODUTOS.ESTOQUEUND)- StrToInt(CurrToStr(ITENS.QTD));
      Div1 =TRUNC(NovaQtd / StrToInt(CurrToStr(QtdUn)));
      Mod1 = ((NovaQtd / StrToInt(CurrToStr(QtdUn)) - Div1) * QTDUND);
      UPDATE PRODUTOS SET PRODUTOS.ESTOQUE = DIV1, PRODUTOS.ESTOQUEUND = 
MOD1 WHERE PRODUTOS.CODIGO = NEW.CODIGO;
      End else begin
      UPDATE PRODUTOS SET PRODUTOS.ESTOQUEUND = PRODUTOS.ESTOQUEUND -
      NEW.ESTOQUEUND WHERE PRODUTOS.CODIGO = NEW.CODIGO;
      end
      END


      END
END
;CREATE TRIGGER TR_CALCITENS_BI FOR ITENS
ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 0
AS
DECLARE VARIABLE NOVAQTD INTEGER;
DECLARE VARIABLE DIV1 INTEGER;
DECLARE VARIABLE MOD1 INTEGER;
DECLARE VARIABLE QTDUN INTEGER;
BEGIN
      IF (DELETING) THEN
      UPDATE PRODUTOS SET PRODUTOS.ESTOQUE = PRODUTOS.ESTOQUE +
      ITENS.QTD WHERE PRODUTOS.CODIGO = OLD.CODIGO;

      IF (UPDATING OR INSERTING) THEN BEGIN
      /* aqui se for produtos com unidades iguais */
      if (Itens.Unidade = 'UN' AND PRODUTOS.UNIDADE = 'UN') THEN BEGIN
      UPDATE PRODUTOS SET PRODUTOS.ESTOQUE = PRODUTOS.ESTOQUE -
      NEW.ESTOQUE WHERE PRODUTOS.CODIGO = NEW.CODIGO;
      END
      /* aqui se for produtos com unidades diferentes */
      if (Itens.Unidade <> 'UN' AND PRODUTOS.UNIDADE <> 'UN') THEN BEGIN
      UPDATE PRODUTOS SET PRODUTOS.ESTOQUE = PRODUTOS.ESTOQUE -
      NEW.ESTOQUE WHERE PRODUTOS.CODIGO = NEW.CODIGO;
      END
      /* aqui se precisa de verificação */
      if (Itens.Unidade = 'UN' AND PRODUTOS.UNIDADE = 'UN') THEN BEGIN
      if (Produtos.EstoqueUnd < Itens.Qtd) then begin
      if (Produtos.QTDUN is null or Produtos.QTD = '') then
      QTDUN = 1;
      else
      QTDUN = PRODUTOS.QTDUN;

      NOVAQTD = ((PRODUTOS.ESTOQUE * StrToInt(CurrToStr(QtdUn)) )+ 
PRODUTOS.ESTOQUEUND)- StrToInt(CurrToStr(ITENS.QTD));
      Div1 =TRUNC(NovaQtd / StrToInt(CurrToStr(QtdUn)));
      Mod1 = ((NovaQtd / StrToInt(CurrToStr(QtdUn)) - Div1) * QTDUND);
      UPDATE PRODUTOS SET PRODUTOS.ESTOQUE = DIV1, PRODUTOS.ESTOQUEUND = 
MOD1 WHERE PRODUTOS.CODIGO = NEW.CODIGO;
      End else begin
      UPDATE PRODUTOS SET PRODUTOS.ESTOQUEUND = PRODUTOS.ESTOQUEUND -
      NEW.ESTOQUEUND WHERE PRODUTOS.CODIGO = NEW.CODIGO;
      end
      END
      END
END
;


Mas se conseguissemos descobrir o motivo do erro "Invalid Cursor" dae 
poderia tentar manipula-lo no sistema para nao ocorrer mais.

Grato,

Rodrigo



----- Original Message ----- 
From: "Felix" <felix2005 em oi.com.br>
To: "'FireBase'" <lista em firebase.com.br>
Sent: Tuesday, September 01, 2009 9:49 AM
Subject: [firebase-br] RES: Invalid Cursor


Para atualização do saldo estoque use uma trigger, é muito mais seguro -
depois de trabalhar desta forma eu nunca tive problemas.

SET TERM ^ ;
CREATE TRIGGER IT_PEDIDO_ESTOQUE FOR IT_PEDIDO ACTIVE
BEFORE INSERT OR UPDATE OR DELETE POSITION 25
AS
BEGIN
    IF (UPDATING OR DELETING) THEN
        UPDATE PRODUTO SET PRODUTO.QUANTIDADE = PRODUTO.QUANTIDADE +
OLD.QTDE WHERE PRODUTO.CODIGOPRO = OLD.CODIGOPRO;
    IF (UPDATING OR INSERTING) THEN
        UPDATE PRODUTO SET PRODUTO.QUANTIDADE = PRODUTO.QUANTIDADE -
NEW.QTDE WHERE PRODUTO.CODIGOPRO = NEW.CODIGOPRO;
END^
SET TERM ; ^

Fco. Felix
Desenvolvimento de Sistemas
www.soltecnologia.com.br

-----Mensagem original-----
De: lista-bounces em firebase.com.br [mailto:lista-bounces em firebase.com.br] Em
nome de Rodrigo
Enviada em: terça-feira, 1 de setembro de 2009 08:24
Para: FireBase
Assunto: [firebase-br] Invalid Cursor

Bom dia a todos,

Estou tendo um problema desde sexta feira passada referente a falha nos
valores do estoque. Tenho um outra tabela que registra todos os movimentos
do estoque e percebi que realmente era alguma falha. Então, comecei a fazer
testes e percebi que se em determinado momento dois usuarios vendessem o
mesmo produto ele nao baixava uma das vendas no Estoque. Uso IBO e Firebird
2.5. Até entao estava usando as transações de forma "otimista" achando que
isso seria muito dificil de acontecer visto que eu projetei o sistema para
iniciar a transação e comittar apenas quando o cliente clicasse no botao
gravar. Então mudei a opção do IBOTransaction, na Opção Isolation para
Comitted (No Rec.Version). Entao comecei a fazer os testes e isso seria o
que eu precisava, visto que apareceria uma mensagem dizendo que a operação
estava travada por outro usuario e eu daria a opção de o usuario tentar
novamente o processo de gravação. Porém começou a aparecer a seguinte
mensagem:

SQL Error Code= -504
Invalid Cursor Reference
Cursor Is Not Open

E esse erro continuou a ser constantes e na tentativa de continuar a venda,
da outros erros e fecha a janela de vendas.
Procurei no google e não achei, procurei no release notes do firebird e la
diz que é um erro de SQLState24 sem dar muitas explicações. "The cursor
identified in the UPDATE,DELETE, SET, or GET statement is not positioned on
a row".

Em outro email Sandro me indicou criar uma nova base de dados no firebird
2.1 e usar um pump para transferir os dados. Fiz isso, e testei na rede e
deu o mesmo problema. Lembrando que o erro só acontece quando dois usuarios
tentam acessar o mesmo registro na rede. Se usar monousuario ou se nao
estiverem atualizando o mesmo registro, o erro não acontece.

Se alguem ja passou por isso e puder me ajudar ou tiver alguma dica.
Agradeço muito.

Grato
Rodrigo


______________________________________________
FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
Para saber como gerenciar/excluir seu cadastro na lista, use:
http://www.firebase.com.br/fb/artigo.php?id=1107
Para consultar mensagens antigas: http://firebase.com.br/pesquisa


______________________________________________
FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
Para saber como gerenciar/excluir seu cadastro na lista, use: 
http://www.firebase.com.br/fb/artigo.php?id=1107
Para consultar mensagens antigas: http://firebase.com.br/pesquisa

__________ NOD32 4385 (20090831) Information __________

This message was checked by NOD32 antivirus system.
http://www.eset.com






Mais detalhes sobre a lista de discussão lista