[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