[firebase-br] Erro em SP Selecionável / Vantagens em seu uso comparando-se ao select

Kleber Caneva kdcc em terra.com.br
Seg Maio 19 16:44:24 -03 2008


Amigo, você pode continuar usando o Select (acho até mais simples nesse 
caso)
Porém se quiser usar Sp não precisa da complicação que você fez, usando 
while e Execute statement.
Basta usar FOR... SELECT
Veja o trecho abaixo.

FOR
   SELECT
     TIPOFAT,
     CODCLI,
     NUMOP,
     LOTE,
     NUMNFMO,
     NUMNFDEV,
     VLRMO,
     VLRDEV,
  FROM UTFATIND
  WHERE TIPOFAT IN ('MOB', 'DMP')
  INTO .......
DO
  BEGIN

       IF (:TIPOFATA = 'MOB' ) THEN
          begin
               TIPO = 'MAO DE OBRA';
               NUMFAT = NUMNFMO;
               VALOR_NF = VALOROMO;
          end
       ELSE IF  (:TIPOFATA = 'BMP' ) THEN

          begin
               TIPO = 'DEVOLUCAO';
               NUMFAT = NUMNFDEV;
               VALOR_NF = VALORDEV;
          end
      ELSE
          begin
               TIPO = 'INDEFINIDO';
               NUMFAT = '';
               VALOR_NF = 0;
          end
     SUSPEND;
  END

[]´s

Kléber Caneva

----- Original Message ----- 
From: "Danilo Coelho" <danilo.s.coelho em gmail.com>
To: <lista em firebase.com.br>
Sent: Monday, May 19, 2008 12:31 PM
Subject: [firebase-br] Erro em SP Selecionável / Vantagens em seu uso 
comparando-se ao select


Olá pessoal,
Estou fazendo uns testes para um post que gostaria de fazer, em um
forum do qual participo, em relação ao uso de procedures selecionáveis
e suas vantagens em comparação ao select; por exemplo, a vantagem de
se usar while, execute statement e por ai vai.
A questão é: não sei se por falta de situações práticas para montar o
sql, as procedures selecionáveis (que fiz) tem sido mais trabalhosas
do que o select para se obter o mesmo resultado...
Abaixo, a estrutura da tabela e o select que me resultou o que eu queria.

CREATE TABLE UTFATIND (
 CODCLI INTEGER DEFAULT 0 NOT NULL,
 NUMOP INTEGER DEFAULT 0 NOT NULL,
 LOTE VARCHAR(20) NOT NULL,
 NUMNFMO INTEGER,
 VLRMO DOUBLE PRECISION,
 NUMNFDEV INTEGER,
 VLRDEV DOUBLE PRECISION,
 TIPOFAT VARCHAR(3) NOT NULL
)

ALTER TABLE UTFATIND
 ADD CONSTRAINT PK_UTFATIND
 PRIMARY KEY (CODCLI, NUMOP, LOTE, TIPOFAT)

SELECT
  CAST(
  CASE
     WHEN(TIPOFAT = 'MOB') THEN 'MAO DE OBRA'
     WHEN(TIPOFAT = 'DMP') THEN 'DEVOLUCAO'
  END AS VARCHAR (15)) AS TIPO,
  CODCLI,
  NUMOP,
  LOTE,
  CASE
     WHEN(TIPOFAT = 'MOB') THEN NUMNFMO
     WHEN(TIPOFAT = 'DMP') THEN NUMNFDEV
  END NUMNF,
  CASE
     WHEN(TIPOFAT = 'MOB') THEN VLRMO
     WHEN(TIPOFAT = 'DMP') THEN VLRDEV
  END VALOR_NF

FROM UTFATIND
WHERE TIPOFAT IN ('MOB', 'DMP')

Nesta procedure (abaixo) minha intenção era obter o resultado que
posteriormente acabei conseguindo fazendo via select (acima) pois me
deparei com este erro:
Column does not belong to referenced table.
Dynamic SQL Error.
SQL error code = -206.
Column unknown.
MOB.
At line 1, column 80.
Gostaria de entender porque deu este erro.

/* codigo da procedure */
CREATE OR ALTER PROCEDURE REL_FAT (
   codcli_ini integer,
   codcli_fin integer,
   numop_ini integer,
   numop_fin integer,
   lote_ini varchar(20),
   lote_fin varchar(20))
returns (
   tipo varchar(13),
   codcli integer,
   numop integer,
   lote varchar(20),
   numnf integer,
   valor numeric(15,2))
as
declare variable v_tipo varchar(4);
declare variable v_campo_nf varchar(10);
declare variable v_campo_vlr varchar(10);
declare variable v_texto_sql varchar(250);
BEGIN
  v_tipo = 'MOB';
  while ((V_TIPO = 'MOB') OR (V_TIPO = 'DMP'))  do
  begin
        V_TEXTO_SQL = '';
        IF (V_TIPO = 'MOB') THEN
        BEGIN
           TIPO = 'MAO DE OBRA';
           V_CAMPO_NF = 'NUMNFMO';
           V_CAMPO_VLR = 'VLRMO';
           V_TEXTO_SQL = 'SELECT CODCLI, NUMOP, LOTE, ' || V_CAMPO_NF ||
                         ', ' || V_CAMPO_VLR || ' FROM UTFATIND ' ||
                         'WHERE TIPOFAT = "MOB" ';
        END
        ELSE
        BEGIN
           TIPO = 'DEVOLUCAO';
           V_CAMPO_NF = 'NUMNFDEV';
           V_CAMPO_VLR = 'VLRDEV';
           V_TEXTO_SQL = 'SELECT CODCLI, NUMOP, LOTE, ' || V_CAMPO_NF ||
                         ', ' || V_CAMPO_VLR || ' FROM UTFATIND ' ||
                         'WHERE TIPOFAT = "DMP" ';
        END

        V_TEXTO_SQL = V_TEXTO_SQL || 'AND CODCLI BETWEEN ' ||
:codcli_ini || ' AND ' || :codcli_fin ||
                      ' AND NUMOP BETWEEN ' || :NUMOP_ini || ' AND '
|| :NUMOP_fin ||
                      ' AND LOTE BETWEEN "' || :LOTE_ini || '" AND "'
|| :LOTE_fin || '"';

        FOR EXECUTE STATEMENT V_TEXTO_SQL
        INTO :codcli, :numop, :lote, :numnf, :valor
        DO
        SUSPEND;
     if (V_TIPO = 'MOB') then
     BEGIN
        V_TIPO = 'DMP';
     END
     ELSE
     BEGIN
        V_TIPO = NULL;
     END
  END
END

Tambem fiz esta procedure usando for select em vez do while mas a
lógica é a mesma, e aconteceu o mesmo erro.
Se puderem exemplificar as vantagens de usar SP Selecionável em
relação ao select fico grato.
Desde já, obrigado.

att,
Danilo S. Coelho.
(obs.: ja enviei este e-mail anteriormente, como fiz uma verificação
nas mensagens postadas (por autor)
e não encontrei-a. Aqui vai novamente, caso eu tenha passado batido e
ja receberão este e-mail, por favor
ignorem.)

______________________________________________
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

E-mail verificado pelo Terra Anti-Spam.
Para classificar como spam, visite
http://mail.terra.com.br/cgi-bin/reportspam.cgi?+_d=SCY0NDU0NzM0I3Blcm0hdGVycmEmMSwxMjExMjEyNTgyLjEzNDcwMy4zMDY2OC5jYWxvbWJhLmhzdC50ZXJyYS5jb20uYnIsNzM2Ng==
Verifique periodicamente a pasta Spam para garantir que apenas mensagens
indesejadas sejam classificadas como Spam.






Mais detalhes sobre a lista de discussão lista