GARANTIR DESCONTO

Fórum Problema com SP executável #47762

28/10/2004

0

Criei uma SP simples do tipo executável para fazer umas totalizações da base de dados. São 4 linhas do tipo SELECT SUM(campo) FROM tabela WHERE ... INTO e no final um somatório envolvendo o resultado de cada select. O estranho é que se uso EXECUTE PROCEDURE a SP retorna os dois parâmetros de saída em branco. Se eu coloco SUSPEND no fim da SP e uso SELECT, funciona direito. Alguém sabe o pq disso, já que a SP deveria ser executável e não selecionável? Inclusive já fiz procedures semelhantes no passado e sempre funcionaram certo, só essa não está dando... O banco foi criado em IB 6 mas agora foi migrado para FB 1.5 (mas já não funcionava antes). Em tempo, cada um dos SELECTS individuais que compõem a SP foi testado individualmente e retornavam o resultado correto. Se não conseguir resolver isso, vou ter que trocar meu IBStoredProc por um IBQuery.


Gandalf.nho

Gandalf.nho

Responder

Posts

28/10/2004

Alexrol

Ola colega

Post sua Sp aqui para que fique mais facil de resolver


Responder

Gostei + 0

28/10/2004

Gandalf.nho

CREATE PROCEDURE ´CALCULA_MOVIMENTOS´
(
PCDEQUIPAMENTO INTEGER
)
RETURNS
(
TOTALESTOQUE DOUBLE PRECISION,
TOTALEMPRESTIMOS DOUBLE PRECISION
)
AS
declare variable vSomaEntrada DOUBLE PRECISION;
declare variable vSomaSaida DOUBLE PRECISION;
declare variable vSomaDevolucoes DOUBLE PRECISION;
BEGIN
vSomaEntrada = 0;
vSomaSaida = 0;
SELECT SUM(QTDMOVIMENTO) FROM MOVIMENT
WHERE CDEQUIPAMENTO = :´PCDEQUIPAMENTO´ AND TPMOVIMENTO = ´E´
INTO :vSomaEntrada;
SELECT SUM(QTDMOVIMENTO) FROM MOVIMENT
WHERE CDEQUIPAMENTO = :´PCDEQUIPAMENTO´ AND TPMOVIMENTO = ´S´
INTO :vSomaSaida;
SELECT SUM(QTDMOVIMENTO) FROM MOVIMENT
WHERE CDEQUIPAMENTO = :´PCDEQUIPAMENTO´ AND TPMOVIMENTO = ´A´
INTO :TOTALEMPRESTIMOS;
SELECT SUM(QTDMOVIMENTO) FROM MOVIMENT
WHERE CDEQUIPAMENTO = :´PCDEQUIPAMENTO´ AND TPMOVIMENTO = ´D´
INTO :vSomaDevolucoes;
TOTALESTOQUE = (vSomaEntrada + vSomaDevolucoes) - (vSomaSaida + TOTALEMPRESTIMOS);
END


Responder

Gostei + 0

29/10/2004

Afarias

note q se ::

SELECT SUM(QTDMOVIMENTO) FROM MOVIMENT
WHERE CDEQUIPAMENTO = :´PCDEQUIPAMENTO´
AND TPMOVIMENTO = ´A´
INTO :TOTALEMPRESTIMOS;

retornar NULO então ::

TOTALESTOQUE = (vSomaEntrada + vSomaDevolucoes) - (vSomaSaida + TOTALEMPRESTIMOS);

Será NULO também!

então, antes do cálculo faça ::

if (TOTALEMPRESTIMOS IS NULL) then
TOTALEMPRESTIMOS = 0;

o mesmo para todas as outras variáveis q entam no cálculo.


Outra coisa, pq o parâmetro PCDEQUIPAMENTO está sendo usando entre aspas???


T+


Responder

Gostei + 0

29/10/2004

Gandalf.nho

note q se :: SELECT SUM(QTDMOVIMENTO) FROM MOVIMENT WHERE CDEQUIPAMENTO = :´PCDEQUIPAMENTO´ AND TPMOVIMENTO = ´A´ INTO :TOTALEMPRESTIMOS; retornar NULO então :: TOTALESTOQUE = (vSomaEntrada + vSomaDevolucoes) - (vSomaSaida + TOTALEMPRESTIMOS); Será NULO também! então, antes do cálculo faça :: if (TOTALEMPRESTIMOS IS NULL) then TOTALEMPRESTIMOS = 0; o mesmo para todas as outras variáveis q entam no cálculo. Outra coisa, pq o parâmetro PCDEQUIPAMENTO está sendo usando entre aspas??? T+


Eu já tentei isso do IS NULL, mas mesmo assim não funciona. Inclusive os
parâmetros de saída não saem com valor NULO e sim em branco, como se a SP não estivesse sendo executada. Quanto as aspas do parâmetro, isso é por causa do recurso de visualizar metadata do IBOConsole, que insiste em mostrar assim, mesmo eu criando as SP sem usar aspas.


Responder

Gostei + 0

30/10/2004

Afarias

e como exatamente vc está executando este procedimento?
e em q ferremanta??


T+


Responder

Gostei + 0

30/10/2004

Gandalf.nho

Estou testando no próprio IBOConsole, usando EXECUTE PROCEDURE


Responder

Gostei + 0

01/11/2004

Afarias

Como havia pensado! O erro não está no Procedimento ou no IB/FB -- está no IBOConsole!

Vc poderia ter testado em seu sistema ou no IBConsole e veria q o resultado aparece.

:D


T+


Responder

Gostei + 0

01/11/2004

_chiappone_

note q se :: SELECT SUM(QTDMOVIMENTO) FROM MOVIMENT WHERE CDEQUIPAMENTO = :´PCDEQUIPAMENTO´ AND TPMOVIMENTO = ´A´ INTO :TOTALEMPRESTIMOS; retornar NULO então :: TOTALESTOQUE = (vSomaEntrada + vSomaDevolucoes) - (vSomaSaida + TOTALEMPRESTIMOS); Será NULO também! então, antes do cálculo faça :: if (TOTALEMPRESTIMOS IS NULL) then TOTALEMPRESTIMOS = 0; o mesmo para todas as outras variáveis q entam no cálculo. Outra coisa, pq o parâmetro PCDEQUIPAMENTO está sendo usando entre aspas??? T+


Colega, soh uma coisinha... se o gandalf estah usando FB 1.5, ele pode usar o comando coalesce, assim ele nao teria problemas com null


SELECT Coalesce(SUM(QTDMOVIMENTO), 0) FROM MOVIMENT 
WHERE CDEQUIPAMENTO = :"PCDEQUIPAMENTO" 
AND TPMOVIMENTO = ´A´ 
INTO :TOTALEMPRESTIMOS;


Sintaxe do coalesce:
Coalesce(<campo>,<valor se null>)


Outra coisa... ateh onde eu sei, pra vc poder exibir algum resultado na sua procedure, vc deve usar o comando
suspend;


sem ele, vc naum concluiu ao firebird que a procedure estah terminada e que voce pode ver os resultados.

Fiz um teste com uma procedure minha agora, retirando o suspend e
ela também parou de funcionar.

Experimente colocar o suspend e os coalesces assim, assim:


CREATE PROCEDURE "CALCULA_MOVIMENTOS"
(
PCDEQUIPAMENTO INTEGER
)
RETURNS
(
TOTALESTOQUE DOUBLE PRECISION,
TOTALEMPRESTIMOS DOUBLE PRECISION
)
AS
declare variable vSomaEntrada DOUBLE PRECISION;
declare variable vSomaSaida DOUBLE PRECISION;
declare variable vSomaDevolucoes DOUBLE PRECISION;
BEGIN
vSomaEntrada = 0;
vSomaSaida = 0;
SELECT coalesce(SUM(QTDMOVIMENTO),0) FROM MOVIMENT
WHERE CDEQUIPAMENTO = :"PCDEQUIPAMENTO" AND TPMOVIMENTO = ´E´
INTO :vSomaEntrada;
SELECT coalesce(SUM(QTDMOVIMENTO),0) FROM MOVIMENT
WHERE CDEQUIPAMENTO = :"PCDEQUIPAMENTO" AND TPMOVIMENTO = ´S´
INTO :vSomaSaida;
SELECT coalesce(SUM(QTDMOVIMENTO),0) FROM MOVIMENT
WHERE CDEQUIPAMENTO = :"PCDEQUIPAMENTO" AND TPMOVIMENTO = ´A´
INTO :TOTALEMPRESTIMOS;
SELECT coalesce(SUM(QTDMOVIMENTO),0) FROM MOVIMENT
WHERE CDEQUIPAMENTO = :"PCDEQUIPAMENTO" AND TPMOVIMENTO = ´D´
INTO :vSomaDevolucoes;
TOTALESTOQUE = (vSomaEntrada + vSomaDevolucoes) - (vSomaSaida + TOTALEMPRESTIMOS);
Suspend;
END


Espero que tenha ajudado!


Responder

Gostei + 0

01/11/2004

Afarias

|Colega, soh uma coisinha... se o gandalf estah usando FB 1.5, ele pode

Não é ELE... é [color=red:8e8551e865][b:8e8551e865]ELA[/b:8e8551e865][/color:8e8551e865]!!!!

;)


|Outra coisa... ateh onde eu sei, pra vc poder exibir algum resultado na
|sua procedure, vc deve usar o comando suspend

só em procedimentos ´selecionáveis´ -- mas ela deseja um procedimento ´executável´


|Fiz um teste com uma procedure minha agora, retirando o suspend e
|ela também parou de funcionar.

pq vc está usando ´select * from procedimento´
faça ´execute procedure procedimento´ e receberá o resultado (1 apenas)


T+


Responder

Gostei + 0

03/11/2004

Gandalf.nho

Você falou para testar em outro lugar, mas no meu sistema tb não dá certo e o IBConsole não funciona com o FB 1.5


Responder

Gostei + 0

04/11/2004

Afarias

Estranho q no seu sistema nào funcione. Qual o comportamento no seu sistema??

Outro lugar onde vc pode testar é no IBExpert -- é uma ferramenta muito boa.


T+


Responder

Gostei + 0

04/11/2004

Gandalf.nho

O comportamento no meu sistema é o mesmo, não retorna nada. Acho que vou ter que deixar como selecionável mesmo e usar um IBQuery para pegar os dados


Responder

Gostei + 0

04/11/2004

Vinicius2k

gandalf,

Assumidamente SPs e Triggers não são meu forte, mas como vc está desistindo, vou arriscar...
Consegui simular seu erro... se a tabela estiver povoada de forma que todas as variáveis recebam algum valor, funciona bem, mas se alguma das variáveis for NULL então, o retorno do parametro em que a variável NULL estiver envolvida também é NULL...
Criei uma tabela assim :
create table MOVIMENT (
  IDMOVIMENTO integer not null,
  CDEQUIPAMENTO integer,
  TPMOVIMENTO char(1),
  QTDMOVIMENTO numeric(15,2),
  constraint PK_MOVIMENT primary key (IDMOVIMENTO)
);


E modifiquei sua procedure assim :
create procedure CALCULA_MOVIMENTOS (
  PCDEQUIPAMENTO integer
)
returns
(
  TOTALESTOQUE double precision,
  TOTALEMPRESTIMOS double precision
)
as
  declare variable SOMAENTRADA double precision;
  declare variable SOMASAIDA double precision;
  declare variable SOMADEVOLUCOES double precision;
begin
  select sum(QTDMOVIMENTO) from MOVIMENT
    where CDEQUIPAMENTO = :PCDEQUIPAMENTO and TPMOVIMENTO = ´E´
    into :SOMAENTRADA;
  /****/
  select sum(QTDMOVIMENTO) from MOVIMENT
    where CDEQUIPAMENTO = :PCDEQUIPAMENTO and TPMOVIMENTO = ´S´
    into :SOMASAIDA;
  /****/
  select sum(QTDMOVIMENTO) from MOVIMENT
    where CDEQUIPAMENTO = :PCDEQUIPAMENTO and TPMOVIMENTO = ´D´
    into :SOMADEVOLUCOES;
  /****/
  select sum(QTDMOVIMENTO) from MOVIMENT
    where CDEQUIPAMENTO = :PCDEQUIPAMENTO and TPMOVIMENTO = ´A´
    into :TOTALEMPRESTIMOS;
  /****/
  if (SOMAENTRADA is null) then SOMAENTRADA = 0;
  if (SOMASAIDA is null) then SOMASAIDA = 0;
  if (SOMADEVOLUCOES is null) then SOMADEVOLUCOES = 0;
  if (TOTALEMPRESTIMOS is null) then TOTALEMPRESTIMOS = 0;
  /****/
  TOTALESTOQUE = (SOMAENTRADA + SOMADEVOLUCOES) - (SOMASAIDA + TOTALEMPRESTIMOS);
end


Desta forma esta funcionando adequadamente, tanto no IBExpert quando dentro da aplicação (IBStoredProc)...
Acho q seu problema é com as variáveis NULL, assim como o Anderson já havia levantado...

Espero ter ajudado...
T+


Responder

Gostei + 0

05/11/2004

Gandalf.nho

Agradeço a ajuda, mas como já tinha falado acima, já tinha tentado esse esquema do IS NULL e agora tentei até COALESCE sem resultado. A questão é que nem nulo retorna os parâmetros, não retorna nada, como se a procedure nem sequer executassse...
Acabei desistindo de fazer ela funcionar como SP executável, coloquei um SUSPEND e vou usar SELECT FROM procedure mesmo. Obrigada a quem tentou ajudar.


Responder

Gostei + 0

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

Aceitar