[firebase-br] Pequena dúvida com Execute Statement
Daisson
daisson em gmail.com
Sex Nov 17 16:22:35 -03 2006
Boa tarde lista.
Tenho uma SP selecionável (o código segue abaixo) e esta ocorrendo um
problema um pouco estranho (pelo menos pra mim). Basicamente a SP serve
para buscar determinados registros excluindo um registro em especial
(que será retornado no último Select).
No primeiro Select (FOR Select) retornam os registros corretos. O
problema ocorre no segundo Select quando ele não traz nenhum registro
(query vazia), e o último registro do primeiro Select é repetido. Óbvio
que usando a cláusula Distinct o problema é resolvido, porém eu achei
estranho o comportamente do Execute Statement. Mesmo não tendo
resultados, o comando Suspend é executado. O que, pra mim, faz com o
que o último registro do primeiro Select seja duplicado.
Alguém pode me ajudar ?
Código da SP:
CREATE PROCEDURE SP_TR04_BASE (
IDEMPRESA NUMERIC(18,0),
IDFILIAL NUMERIC(18,0),
CODIGOIMPOSTO VARCHAR(6),
INICIO VARCHAR(10),
FIM VARCHAR(10))
RETURNS (
CONTA NUMERIC(6,0),
NOME VARCHAR(100),
BASEDEDUCAO NUMERIC(4,2),
VALOR NUMERIC(15,2),
PERCAJUSTE NUMERIC(9,4),
BASEDECALCULO NUMERIC(15,2),
ALIQUOTA NUMERIC(9,4),
VLRIMPOSTO NUMERIC(15,2),
IMPOSTO VARCHAR(6))
AS
DECLARE VARIABLE V_BASEDEDUCAO NUMERIC(4,2);
DECLARE VARIABLE V_SQL VARCHAR(5000);
BEGIN
/* Inicializando variável V_BASEDEDUCAO */
V_BASEDEDUCAO = 0;
/* Conforme o código do Imposto no parâmetro, atualizamos a variável
V_BASEDEDUCAO com o valor específico da Dedução do Imposto. */
IF ((:CODIGOIMPOSTO = '0102') OR (:CODIGOIMPOSTO = '0202')) THEN
V_BASEDEDUCAO = 10;
ELSE IF ((:CODIGOIMPOSTO = '0402') AND (:V_BASEDEDUCAO <= 0)) THEN
V_BASEDEDUCAO = 9;
ELSE IF ((:CODIGOIMPOSTO = '0501') AND (:V_BASEDEDUCAO <= 0)) THEN
V_BASEDEDUCAO = 5;
ELSE IF ((:CODIGOIMPOSTO = '0501') AND (:V_BASEDEDUCAO <= 0)) THEN
V_BASEDEDUCAO = 5;
ELSE
V_BASEDEDUCAO = 3;
/* Simplesmente devole ao parâmetro de Saída o código do Imposto de
entrada */
IMPOSTO = :CODIGOIMPOSTO;
/* Atualizamos a variável V_SQL com o SQL default para, mais abaixo,
analisarmos determinadas condições para utilização desse SQL. */
V_SQL = 'SELECT CO01_PLANO.CONTA,' ||
' CO01_PLANO.NOME,' ||
' TR04_BASE.BASEDEDUCAO,' ||
' TR04_BASE.VALOR,' ||
' TR04_BASE.PERCAJUSTE,' ||
' TR04_BASE.BASEDECALCULO,' ||
' TR04_BASE.ALIQUOTA,' ||
' TR04_BASE.VLRIMPOSTO' ||
' FROM TR04_BASE' ||
' LEFT JOIN CO01_PLANO' ||
' ON (TR04_BASE.IDPLANO = CO01_PLANO.IDPLANO)' ||
' WHERE TR04_BASE.IDEMPRESA = ' || :IDEMPRESA;
IF (:IDFILIAL IS NOT NULL) THEN
BEGIN
V_SQL = :V_SQL ||
' AND TR04_BASE.IDFILIAL = ' || :IDFILIAL;
END
/* Analisando a Inclusão/Exclusão das Receitas. */
IF ((:CODIGOIMPOSTO = '0102') OR (:CODIGOIMPOSTO = '0202')) THEN
V_SQL = :V_SQL ||
' AND TR04_BASE.BASEDEDUCAO NOT IN (1,2)';
/* Término da atualização da variável que contém o SQL */
V_SQL = :V_SQL ||
' AND TR04_BASE.IMPOSTO = ' || '''' || :CODIGOIMPOSTO || '''' ||
' AND TR04_BASE.INICIO >= ' || '''' ||:INICIO || '''' ||
' AND TR04_BASE.FIM = ' || '''' || :FIM || '''' ||
' AND TR04_BASE.BASEDEDUCAO <> ' || :V_BASEDEDUCAO ||
' ORDER BY TR04_BASE.BASEDEDUCAO';
FOR EXECUTE STATEMENT :V_SQL
INTO :CONTA,
:NOME,
:BASEDEDUCAO,
:VALOR,
:PERCAJUSTE,
:BASEDECALCULO,
:ALIQUOTA,
:VLRIMPOSTO DO
BEGIN
SUSPEND;
END
/* Atualizamos o SQL para buscar SOMENTE o registro com a Dedução do
Imposto */
V_SQL = 'SELECT CO01_PLANO.CONTA,' ||
' CO01_PLANO.NOME,' ||
' TR04_BASE.BASEDEDUCAO,' ||
' TR04_BASE.VALOR,' ||
' TR04_BASE.PERCAJUSTE,' ||
' TR04_BASE.BASEDECALCULO,' ||
' TR04_BASE.ALIQUOTA,' ||
' TR04_BASE.VLRIMPOSTO' ||
' FROM TR04_BASE' ||
' LEFT JOIN CO01_PLANO' ||
' ON (TR04_BASE.IDPLANO = CO01_PLANO.IDPLANO)' ||
' WHERE TR04_BASE.IDEMPRESA = ' || :IDEMPRESA;
IF (:IDFILIAL IS NOT NULL) THEN
BEGIN
V_SQL = :V_SQL ||
' AND TR04_BASE.IDFILIAL = ' || :IDFILIAL;
END
V_SQL = :V_SQL ||
' AND TR04_BASE.IMPOSTO = ' || '''' || :CODIGOIMPOSTO || '''' ||
' AND TR04_BASE.INICIO >= ' || '''' ||:INICIO || '''' ||
' AND TR04_BASE.FIM = ' || '''' || :FIM || '''' ||
' AND TR04_BASE.BASEDEDUCAO = ' || :V_BASEDEDUCAO ||
' ORDER BY TR04_BASE.BASEDEDUCAO';
EXECUTE STATEMENT :V_SQL
INTO :CONTA,
:NOME,
:BASEDEDUCAO,
:VALOR,
:PERCAJUSTE,
:BASEDECALCULO,
:ALIQUOTA,
:VLRIMPOSTO;
SUSPEND;
END^
Obrigado.
--
Daisson
Pinhalzinho - SC
Mais detalhes sobre a lista de discussão lista