Erro de conversão de tipo (DECODE ou LPAD)

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Boa tarde pessoal.

O erro de conversão de tipos pode estar relacionado ao uso equivocado de algumas destas funções abaixo:

Selecionar tudo


 DECODE(FORMA_PAGTO, '-1', '536', '306') AS FPAGTO

 e ainda testo este valor dentro de um cursor

 IF vTST_CURSOR2.FPAGTO = '536' THEN

 
Onde FORMA_PAGTO é tipo number.

Também estou desconfiado destas outras duas linhas, a minha dúvida é saber qual valor e tipo de dado a função vai me retornar na saida.

Selecionar tudo


 LPAD( '306', 3, '0')               ||
TO_CHAR(LPAD( vTST_CURSOR2.VALOR,  10, '0'), '0999999D99', 'nls_numeric_characters='',.'''));

 
Grato a quem puder me ajudar.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Olá, Tinho.

Fica mais simples ajudar se você puder postar a mensagem de erro completa e o código que está executando.
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Olá o erro é o seguinte:

Selecionar tudo


 ORA-06502: PL/SQL: numeric or value error: character to number conversion error -6502

 
Já havia pesquisado sobre o mesmo e encontrei a seguinte descrição:

Selecionar tudo


 Causa: Um aritmética, numérico, string, conversão ou erro de restrição ocorreu. 

Por exemplo, este erro ocorre se for feita uma tentativa para atribuir o valor NULL a uma variável declarada NOT NULL, ou se é feita uma tentativa para atribuir um número inteiro maior do que 99 para uma variável declarada NÚMERO 

Ação: Alterar os dados, como ele é manipulado ou como é declarado para que os valores não violam restrições. 

 
Grato.[/quote]
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Apesar de eu achar difícil o erro estar na passagem dos parâmetros e não sei se isto ajuda mas eles são usados para executar a proc:

Selecionar tudo


P_DIRETORIO    IN VARCHAR2,
P_DATA_INI     IN DATE,
P_DATA_FIM     IN DATE,
P_CLIENT       IN VARCHAR2,
P_CLIENT_GROUP IN VARCHAR2,
P_CUSTOMER     IN VARCHAR2,
P_TIPOFILE     IN VARCHAR2,
P_TIPO         IN VARCHAR2 DEFAULT 'P',
P_NOTA         IN VARCHAR2 DEFAULT NULL

E está sendo chamada manualmente assim:

Selecionar tudo


begin
 USEROPER.SP_GERA_DESCFOLHA_MWM('P:\RNETO\', '11-JAN-2010','10-FEB-2010','T','T','CT000224','0','P',null);
end;

Estranhamente o erro ocorre quando esta proc é executada pelo "front-end" - aplicação, mas acredito que se fosse o erro da aplicação daria erros em proc semelhantes, pois as chamadas e os parametros são os mesmos.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Não sei quanto ao erro numérico, mas para detectar onde está o problema você pode tentar isolar esses seus trechos suspeitos colocando eles entre BEGIN ... EXCEPTION END;

Capture o erro nesse bloco e exiba um erro customizado por exemplo com RAISE_APPLICATION_ERROR passando o SQLERRM como texto dele.

Selecionar tudo

... -- restante do código
BEGIN
  --comando suspeito de estar causando erro
EXCEPTION
  WHEN OTHERS THEN
    RAISE_APPLICATION_ERROR(-20000, 'ERRO NO TRECHO X: ' || SQLERRM);
END;
  --- continua com o código normalmente
...
Como boa prática você pode adotar o hábito de colocar SELECTs entre BEGIN..EXCEPTION END; pois facilita bastante para detectar onde disparou o erro. Só não esqueça nunca de dar um RAISE; ou RAISE_APPLICATION_ERROR, para não "engolir" uma exception por acidente.

Outra coisa, você está passando duas datas por parâmetro da forma '11-JAN-2010'. Use sempre uma função TO_DATE com máscara de formato nesses casos, ou o Oracle faz uma conversão implícita para você e qualquer mudança de configuração interna do servidor no NLS_DATE_FORMAT ou mesmo um ALTER SESSION/DBMS_SESSION por outra parte de sua aplicação podem gerar uma infinidade de bugs do nada num código que até o dia anterior funcionava sem erros.

Eu teria muitos cabelos brancos a menos se esse conselho fosse seguido sempre...
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Muito obrigado, vou seguir suas recomendações.

Falando em execeções o código já trata isso da seguinte maneira:

Selecionar tudo


 EXCEPTION
 WHEN  OTHERS THEN
   vERR_CODE      := SQLCODE;
   vERR_MSG     := SUBSTR(SQLERRM, 1, 200);
   Sp_Envia_Email_Erro_Oracle(vERR_MSG || ' ' ||
                              vERR_CODE, 'xxxx@xxx.com.br',
                                         --'xxx@xxx.com.br',
                                         'ERRO NA PROCEDURE SP_GERA_DESCFOLHA_MWM');
END;
 
 

Grato.
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Bom dia pessoal.

Perdoe-me a "leigice" mas não consigo encontrar onde está o erro, uma que executando ela pelo gerenciador TOAD o mesmo não é exibido, apenas na aplicação:

Segue a proc abaixo:

Selecionar tudo


 CREATE OR REPLACE PROCEDURE USEROPER.SP_GERA_DESCFOLHA_MWM
(
  P_DIRETORIO    IN VARCHAR2,
  P_DATA_INI     IN DATE,
  P_DATA_FIM     IN DATE,
  P_CLIENT       IN VARCHAR2,
  P_CLIENT_GROUP IN VARCHAR2,
  P_CUSTOMER     IN VARCHAR2,
  P_TIPOFILE     IN VARCHAR2,
  P_TIPO         IN VARCHAR2 DEFAULT 'P',
  P_NOTA         IN VARCHAR2 DEFAULT NULL
) IS

vSQL                VARCHAR2(200);
vERR_CODE           VARCHAR2(15);
vERR_MSG            VARCHAR2(200);

vCONVENIADO         VARCHAR2(3) := '030';
vCODFILIAL_1        VARCHAR2(3);
vDATA               VARCHAR2(10);

SAIDA1              SYS.UTL_FILE.FILE_TYPE;
vNAME_FILE          VARCHAR2(100);
vDIRECTORY          VARCHAR2(100);
vDIRECTORY_PATH     VARCHAR2(100);

vCONTADOR           NUMBER;

-------------------------------------------------------------------------------------------------------------------
/******************************************************************************************************************/
/**************************************** DESCONTO EM FOLHA (600) *************************************************/
/******************************************************************************************************************/

-- PERÍODO

CURSOR P_DESCFOLHA_PERIODO ( P_DATA_INI     IN DATE,
                             P_DATA_FIM     IN DATE,
                             P_CLIENT       IN VARCHAR2,
                             P_CLIENT_GROUP IN VARCHAR2,
                             P_CUSTOMER     IN VARCHAR2) IS
-- desconto
SELECT MATRICULA,
       SUM(VALOR_DESCONTO) AS VALOR,
       COD_FILIAL,
       FPAGTO
FROM(
    SELECT
           PATIENT_PIN_NUMBER      AS MATRICULA,
           DESC_FOLHA_PAGTO        AS VALOR_DESCONTO,
            CASE
                 WHEN MB.CLIENT_ID IN ('CANOAS') THEN LPAD('002', 3, '0')
                 ELSE                                 LPAD('003', 3, '0')
            END AS COD_FILIAL,
            DECODE(FORMA_PAGTO, '-1', '536', '306') AS FPAGTO
            FROM MEMBER MB, V_MOVIMENTACAO VF
            WHERE MB.MEMBER_ID        = VF.VIDA                       AND
                  MB.CUSTOMER_ID      = VF.COD_PLANO                  AND
                  MB.PERSON_CODE      = VF.PERSON_CODE                AND
                  MB.CLIENT_GROUP_ID  = VF.CLIENT_GROUP_ID            AND
                  MB.CLIENT_ID        = VF.CLIENT_ID                  AND
                  VENDA               = 'S'                           AND
                  STATUS_VENDA        = 'P'                           AND
                  STATUS_FATURAMENTO  = '0'                           AND
                  STATUS_COBRANCA     = '0'                           AND
                  FORMA_PAGTO         = '-1'                          AND
                  DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 2 ), VF.CLIENT_GROUP_ID) = DECODE(P_CLIENT_GROUP,'T',DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 2 ), VF.CLIENT_GROUP_ID) ,P_CLIENT_GROUP) AND
                  DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 1 ), VF.CLIENT_ID)       = DECODE(P_CLIENT,'T',DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 1 ), VF.CLIENT_ID) ,P_CLIENT) AND
                  COD_PLANO   =       P_CUSTOMER    AND
                  DATE_FILLED BETWEEN P_DATA_INI AND
                                      P_DATA_FIM)
                 GROUP BY MATRICULA, COD_FILIAL, FPAGTO
UNION ALL
-- devolucao
SELECT MATRICULA,
       SUM(VALOR_DESCONTO),
       COD_FILIAL,
       FPAGTO
FROM(
    SELECT
           PATIENT_PIN_NUMBER           AS MATRICULA,
           DESC_FOLHA_PAGTO        AS VALOR_DESCONTO,
            CASE
                 WHEN MB.CLIENT_ID IN ('CANOAS') THEN LPAD('002', 3, '0')
                 ELSE                                 LPAD('003', 3, '0')
            END AS COD_FILIAL,
            DECODE(FORMA_PAGTO, '-1', '536', '306') AS FPAGTO
             FROM MEMBER MB, V_MOVIMENTACAO VF
                  WHERE  MB.MEMBER_ID        = VF.VIDA            AND
                         MB.CUSTOMER_ID      = VF.COD_PLANO       AND
                         MB.PERSON_CODE      = VF.PERSON_CODE     AND
                         MB.CLIENT_GROUP_ID  = VF.CLIENT_GROUP_ID AND
                         MB.CLIENT_ID        = VF.CLIENT_ID       AND
                         VENDA               = 'S'                AND
                         STATUS_VENDA        = 'P'                AND
                         STATUS_FATURAMENTO  = '0'                AND
                         STATUS_COBRANCA     = '0'                AND
                         FORMA_PAGTO         in ('-3', '0')               AND
                         DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 2 ), VF.CLIENT_GROUP_ID) = DECODE(P_CLIENT_GROUP,'T',DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 2 ), VF.CLIENT_GROUP_ID) ,P_CLIENT_GROUP) AND
                         DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 1 ), VF.CLIENT_ID)       = DECODE(P_CLIENT,'T',DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 1 ), VF.CLIENT_ID) ,P_CLIENT) AND
                         COD_PLANO   =       P_CUSTOMER AND
                         DATE_FILLED BETWEEN P_DATA_INI AND
                                            P_DATA_FIM)
                        GROUP BY MATRICULA, COD_FILIAL, FPAGTO
                        ORDER BY COD_FILIAL;
-- NOTA

CURSOR P_DESCFOLHA_NOTA (P_NOTA IN VARCHAR2) IS
-- desconto
SELECT MATRICULA,
       SUM(VALOR_DESCONTO) AS VALOR,
       COD_FILIAL,
       FPAGTO
FROM(
    SELECT
           PATIENT_PIN_NUMBER      AS MATRICULA,
           DESC_FOLHA_PAGTO        AS VALOR_DESCONTO,
            CASE
                 WHEN MB.CLIENT_ID IN ('CANOAS') THEN LPAD('002', 3, '0')
                 ELSE                                 LPAD('003', 3, '0')
            END AS COD_FILIAL,
            DECODE(FORMA_PAGTO, '-1', '536', '306') AS FPAGTO
            FROM MEMBER MB, V_MOVIMENTACAO VF
                 WHERE  MB.MEMBER_ID        = VF.VIDA            AND
                        MB.CUSTOMER_ID      = VF.COD_PLANO       AND
                        MB.PERSON_CODE      = VF.PERSON_CODE     AND
                        MB.CLIENT_GROUP_ID  = VF.CLIENT_GROUP_ID AND
                        MB.CLIENT_ID        = VF.CLIENT_ID       AND
                        VF.NUM_NF_CONV      = P_NOTA             AND
                        FORMA_PAGTO         = '-1')
                        GROUP BY MATRICULA, COD_FILIAL, FPAGTO
                        UNION ALL
-- devolucao
SELECT MATRICULA,
       SUM(VALOR_DESCONTO) AS VALOR,
       COD_FILIAL,
       FPAGTO
FROM(
    SELECT
           PATIENT_PIN_NUMBER           AS MATRICULA,
           DESC_FOLHA_PAGTO        AS VALOR_DESCONTO,
            CASE
                 WHEN MB.CLIENT_ID IN ('CANOAS') THEN LPAD('002', 3, '0')
                 ELSE                                 LPAD('003', 3, '0')
            END AS COD_FILIAL,
            DECODE(FORMA_PAGTO, '-1', '536', '306') AS FPAGTO
            FROM MEMBER MB, V_MOVIMENTACAO VF
                 WHERE  MB.MEMBER_ID        = VF.VIDA            AND
                        MB.CUSTOMER_ID      = VF.COD_PLANO       AND
                        MB.PERSON_CODE      = VF.PERSON_CODE     AND
                        MB.CLIENT_GROUP_ID  = VF.CLIENT_GROUP_ID AND
                        MB.CLIENT_ID        = VF.CLIENT_ID       AND
                        VF.NUM_NF_CONV      = P_NOTA             AND
                        FORMA_PAGTO         = '-3')
                        GROUP BY MATRICULA, COD_FILIAL, FPAGTO
                    ORDER BY COD_FILIAL;

-------------------------------------------------------------------------------------------------------------------

/* DECLARACAO DOS CURSORES */

vTST_CURSOR         P_DESCFOLHA_PERIODO%ROWTYPE; -- PERIODO
vTST_CURSOR2        P_DESCFOLHA_NOTA%ROWTYPE;    -- NOTA

-------------------------------------------------------------------------------------------------------------------
BEGIN
      vCODFILIAL_1 := '0';
      vCONTADOR := 0;

      vSQL := 'ALTER SESSION SET NLS_DATE_FORMAT = "DD-MM-YYYY"';
      EXECUTE IMMEDIATE VSQL;
      SELECT Pega_Path_Oracle(UPPER(P_DIRETORIO)) INTO vDIRECTORY_PATH FROM DUAL;
      SELECT TO_CHAR(P_DATA_FIM,'YYYY-MM') INTO VDATA FROM DUAL;

-------------------------------------------------------------------------------------------------------------------
 IF P_TIPO <> 'N' THEN -- PERÍODO

        IF NOT P_DESCFOLHA_PERIODO%ISOPEN THEN
         OPEN P_DESCFOLHA_PERIODO ( P_DATA_INI,
                                    P_DATA_FIM,
                                    P_CLIENT,
                                    P_CLIENT_GROUP,
                                    P_CUSTOMER );
        END IF;

          LOOP
             FETCH P_DESCFOLHA_PERIODO INTO vTST_CURSOR;
             EXIT WHEN P_DESCFOLHA_PERIODO%NOTFOUND;

                 IF vTST_CURSOR.COD_FILIAL <> vCODFILIAL_1 THEN
                    IF vCONTADOR > 0 THEN
                       SYS.UTL_FILE.FCLOSE(SAIDA1);
                    END IF;

                    vCONTADOR := vCONTADOR + 1 ;
                    vCODFILIAL_1 := vTST_CURSOR.COD_FILIAL;
                    vNAME_FILE := 'MWM_'||VDATA|| '_' || vCODFILIAL_1 || '.TXT';
                    SAIDA1     := SYS.UTL_FILE.FOPEN( VDIRECTORY_PATH, vNAME_FILE, 'W');

                    -- HEADER
                    SYS.UTL_FILE.PUT_LINE( SAIDA1,
                                     LPAD( vCONVENIADO, 3, '0')                    ||
                                     REPLACE(LAST_DAY(TO_DATE(SYSDATE)),'-','/') ||
                                     vTST_CURSOR.COD_FILIAL);
                 END IF;

                   -- CORPO

                 IF vTST_CURSOR.FPAGTO = '600' THEN

                      SYS.UTL_FILE.PUT_LINE( SAIDA1,
                                     LPAD( vTST_CURSOR.MATRICULA, 6, '0')   ||
                                     -- LPAD( '600', 3, 0)               ||
                                     vTST_CURSOR.FPAGTO ||
                                     TO_CHAR(LPAD( vTST_CURSOR.VALOR, 10, '0'), '0999999D99', 'nls_numeric_characters='',.'''));
                                     --LPAD( vTST_CURSOR.VALOR, 10, '0'), '0999999D99', 'nls_numeric_characters='',.''');
                 ELSE
                    SYS.UTL_FILE.PUT_LINE( SAIDA1,
                                     LPAD( vTST_CURSOR.MATRICULA, 6, '0')   ||
                                     --LPAD( '284', 3, 0)               ||
                                     vTST_CURSOR.FPAGTO ||
                                     TO_CHAR(LPAD( vTST_CURSOR.VALOR, 10, '0'), '0999999D99', 'nls_numeric_characters='',.'''));
                                     --LPAD( vTST_CURSOR.VALOR, 10, '0'), '0999999D99', 'nls_numeric_characters='',.''');
                 END IF;

                 IF vTST_CURSOR.COD_FILIAL <> vCODFILIAL_1 THEN
                    vCODFILIAL_1 := vTST_CURSOR.COD_FILIAL;
                 END IF;
          END LOOP;
 ELSE -- NOTA
     IF NOT P_DESCFOLHA_NOTA%ISOPEN THEN
         OPEN P_DESCFOLHA_NOTA (  P_NOTA );
        END IF;

          LOOP
             FETCH P_DESCFOLHA_NOTA INTO vTST_CURSOR2;
             EXIT WHEN P_DESCFOLHA_NOTA%NOTFOUND;

                 IF vTST_CURSOR2.COD_FILIAL <> vCODFILIAL_1 THEN

                    IF vCONTADOR > 0 THEN
                       SYS.UTL_FILE.FCLOSE(SAIDA1);
                    END IF;

                    vCONTADOR := vCONTADOR + 1 ;
                    vCODFILIAL_1 := vTST_CURSOR2.COD_FILIAL;
                    vNAME_FILE := 'MWM_'||VDATA|| '_' || vCODFILIAL_1 || '.TXT';
                    SAIDA1     := SYS.UTL_FILE.FOPEN( VDIRECTORY_PATH, vNAME_FILE, 'W');

                    -- HEADER
                    SYS.UTL_FILE.PUT_LINE( SAIDA1,
                                     LPAD( vCONVENIADO, 3, '0')                    ||
                                     REPLACE(LAST_DAY(TO_DATE(SYSDATE)),'-','/') ||
                                     vTST_CURSOR2.COD_FILIAL);
                 END IF;

                   -- CORPO 

                 IF vTST_CURSOR2.FPAGTO = '536' THEN

                      SYS.UTL_FILE.PUT_LINE( SAIDA1,
                                     LPAD( vTST_CURSOR2.MATRICULA, 6, '0')   ||
                                     LPAD( '536', 3, '0')               ||
                                     --vTST_CURSOR.FPAGTO ||
                                     TO_CHAR(LPAD( vTST_CURSOR2.VALOR, 10, '0'), '0999999D99', 'nls_numeric_characters='',.'''));
                                     --LPAD( vTST_CURSOR2.VALOR, 10, '0'), '0999999D99', 'nls_numeric_characters='',.''');
                 ELSE
                    SYS.UTL_FILE.PUT_LINE( SAIDA1,
                                     LPAD( vTST_CURSOR2.MATRICULA, 6, '0')   ||
                                     LPAD( '306', 3, '0')               ||
                                     --vTST_CURSOR.FPAGTO ||
                                     TO_CHAR(LPAD( vTST_CURSOR2.VALOR, 10, '0'), '0999999D99', 'nls_numeric_characters='',.'''));
                                     --LPAD( vTST_CURSOR2.VALOR, 10, '0'), '0999999D99', 'nls_numeric_characters='',.''');                                     
                 END IF;

                 IF vTST_CURSOR2.COD_FILIAL <> vCODFILIAL_1 THEN
                    vCODFILIAL_1 := vTST_CURSOR2.COD_FILIAL;
                 END IF;
          END LOOP;
        END IF;
            SYS.UTL_FILE.FCLOSE(SAIDA1);

 
A quem puder ajudar, muitíssimo obrigado.
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Gente, acho que achei o erro de conflito de conversão de tipo. Estava fazendo alguns testes e ocorreu o seguinte:

Selecionar tudo


 Num SELECT quando altero a primeira linha para a segunda:

 --SUM(VALOR_DESCONTO) AS VALOR,
   TO_CHAR(LPAD( SUM(VALOR_DESCONTO), 10, '0'), '0999999D99', 'nls_numeric_characters='',.''')  

 Recebo a seguinte mensagem de erro:

 ORA-01722: número inválido 
 Causa: A tentativa de conversão de uma seqüência de caracteres para um número falhou porque a seqüência de  caracteres não foi uma literal numérica válida. Apenas os campos numéricos ou campos de caracteres que contém  dados numéricos podem ser utilizados em funções aritméticas ou expressões. Apenas os campos numéricos pode ser  adicionado ou subtraído de datas. 
 Ação: Verifique as cadeias de caracteres na função ou expressão. Verifique se eles contêm apenas números, um   sinal, um ponto decimal, eo caráter "E" ou "E" e repita a operação.  

 Como posso resolver essa conversão, sendo que tenho que utlizar esta mascara para moeda?

 
Porém já é um erro diferente recebido no front-end, mas acredito ser bem possível que eles estejam relacionados, o erro é o seguinte:

Selecionar tudo


 ORA-06502: PL/SQL: numeric or value error: character to number conversion error -6502

 
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Tenta retirar aquele LPAD que está sendo usado ali, pois ele não está servindo para nada da forma como está ali, e provavelmente está causando uma conversão implícita inesperada.

O erro que está dando é só em ambiente de produção e você não pode mexer?

Se for em ambiente de desenvolvimento tente o que sugeri, por gentileza: "anexe" no tratamento de erro uma mensagem customizada e de um re-raise sempre. Da forma que você postou acima você está mandando o erro via e-mail mas o erro está sendo engolido pela aplicação e isso é muito ruim. E se o envio de e-mail der erro também? ninguém vai ficar sabendo que ocorreu erro.
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Realmente, tirando o LPAD, funcionou, mas neste caso estou utilizando o LPAD para complementar com zeros a esquerda do valor para respeitar o layout definido pelo cliente, pois todo esse procedimento resultará em um arquivo texto, e se eu retira-lo, como vou tratar isso? Ou essa mascara que estou utlizando já preenche automaticamente?
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

O TO_CHAR com '0xxx' no formato da máscara já faz a mesma coisa.

Na minha versão do Oracle (10.2) não estava dando erro, mas de repente era alguma questão específica da sua versão que causava o erro ou algum dado de input da sua tabela que eu não testei.
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Obrigado, você já me ajudou bastante.

Mas mesmo utlizando o TO_CHAR, como faço para que o mesmo respeite o tamanho especificado do campo?

Pois com este formato que estou utilizando para moeda ("0999999D99") eu consigo especificar para ser completado com zeros a esquerda, a minha dúvida é, como faço para ele respeitar o tamanho exato de campos que eu preciso? Como eu trunco o tamanho para um valor fixo?
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Além disso como faço para saber qual é o comportamento do Oracle, quanto ao que ele converte implicitamente ou não, um exemplo que me causou dúvida foi o seguinte:

Na mesma proc tenho uma condição que verifica se o valor de FPGATO que é o tipo númerico é igual a um número, se eu colocasse esse valor de comparação entre aspas, qual seria a o comportamento do "Oracle" na hora da execução desta proc, ele automaticamente faria a conversão ou geraria um erro:

Selecionar tudo


IF vTST_CURSOR2.FPAGTO = 536 THEN

Também tem outro caso especifico, no uso do DECODE, que também é uma comparação, ou seja, se eu colocasse os valores a serem comparados entre aspas, geraria um erro?

Selecionar tudo


DECODE(FORMA_PAGTO, -1, 536, 306) AS FPAGTO

Grato.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Você pode testar você mesmo tudo isso, sabe como dizem, "ensinar a pescar". Respondendo às suas dúvidas, sim o Oracle converte de forma oculta por você e não retorna erro a menos que durante essa conversão implícita tenha sido encontrada alguma incompatibilidade entre os tipos.

O decode é um pouco diferente porque o tipo do output é dado pelo tipo do terceiro argumento. Então todos os outputs precisam ser do mesmo tipo ou, pelo menos, convertíveis entre si.

Veja os exemplos:

Selecionar tudo

SQL> with t as (
  2  select -1 as FORMA_PAGTO from dual union all
  3  select 1 from dual union all
  4  select 2 from dual)
  5  --
  6  select decode(forma_pagto, 1, '10', 2, 20, 'OUTROS') AS FPAGTO
  7    from t;
 
FPAGTO
------
OUTROS
10
20
 
SQL> 
SQL> with t as (
  2  select -1 as FORMA_PAGTO from dual union all
  3  select 1 from dual union all
  4  select 2 from dual)
  5  --
  6  select decode(forma_pagto, 1, 10, 2, 20, 'OUTROS') AS FPAGTO
  7    from t;
 
with t as (
select -1 as FORMA_PAGTO from dual union all
select 1 from dual union all
select 2 from dual)
--
select decode(forma_pagto, 1, 10, 2, 20, 'OUTROS') AS FPAGTO
  from t
 
ORA-01722: invalid number
 
SQL> 
O 1o exemplo funciona perfeitamente, pois especifiquei o argumeno de saída como '10', ou seja, um caractere. Logo ele converteu implicitamente o 20 para '20' e fez o output de 'OUTROS' também corretamente.

No 2o exemplo ocorreu erro. Mas por qual motivo? Porque o primeiro argumento de saída foi especificado como 10, sem apóstrofes, ou seja: um número. Assim, o DECODE espera que todos os outputs listados sejam também números. O 20 é um número, ok. Mas ao tentar converter 'OUTROS' para número é disparado um erro.

E lembre, eu não descobri nada disso no chute ou tentando exaustivamente todas possibilidades. Está tudo escrito e documentado.
Crie o hábito de sempre que tiver uma dúvida pesquisar na documentação em http://tahiti.oracle.com

Para o decode está claramente escrito em
http://download.oracle.com/docs/cd/E118 ... ons047.htm
Oracle automatically converts expr and each search value to the data type of the first search value before comparing. Oracle automatically converts the return value to the same data type as the first result.
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Muito obrigado novamente, vou procurar criar o hábito de consultar os manuais indicados, e uma atitude "apelativa" minha era ir testando exaustivamente diversas possibilidades (tentativa de erro e acerto) e pode deixar que vou aprender a pescar, value mesmo pelas dicas.
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Neste caso está dando erro:

Selecionar tudo


 DECODE(FORMA_PAGTO, -1, '536', '306') AS FPAGTO

 Ou seja, se FORMA_PAGTO for -1 Então imprime '536' Senão '306'

E da maneira como você descreveu no exemplo, não é gerado erro algum:

Selecionar tudo


with t as ( 
 select -1 as FORMA_PAGTO from dual union all 
  select 1 from dual union all 
  select 2 from dual) 
  select decode(forma_pagto, -1, '10', '20') AS FPAGTO 
  from t;

Já parei para analisar porém não consegui identificar o porque do erro "ORA-01722: invalid number".
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Significa que sua coluna FORMA_PAGTO é do tipo caractere, mas tem ao mesmo tempo linhas onde há números e outras linhas onde há letras, e ele está tentando converter as letras para número, pois seu primeiro argumento de busca informado foi um number (-1).

Selecionar tudo

SQL> with t as (
  2   select '-1' as FORMA_PAGTO from dual union all
  3    select '1' from dual union all
  4    select '2' from dual union all
  5    select 'ABC' from dual)
  6    select decode(forma_pagto, -1, '10', '20') AS FPAGTO
  7    from t;
 
with t as (
 select '-1' as FORMA_PAGTO from dual union all
  select '1' from dual union all
  select '2' from dual union all
  select 'ABC' from dual)
  select decode(forma_pagto, -1, '10', '20') AS FPAGTO
  from t
 
ORA-01722: invalid number
 
SQL> 
Tente modificar para:

Selecionar tudo

DECODE(FORMA_PAGTO, '-1', '536', '306') AS FPAGTO
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Já havia tentado isso também porém o erro persiste.

Att.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

A coluna FORMA_PAGTO está na tabela V_MOVIMENTACAO?

Se sim, rode o SQL abaixo:

Selecionar tudo

select distinct forma_pagto from v_movimentacao;
e depois poste o resultado dos seguintes comandos por favor:

Selecionar tudo

desc v_movimentacao;
select * from v$version;
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Desculpe-me mas já estou confuso, pois quando executo o seguinte "script" ele executa:

Selecionar tudo


SELECT /*+INDEX(VF V_MOV_PLANO_DATE_FILLED_IDX)*/
                 PATIENT_PIN_NUMBER           AS MATRICULA,  
                 --DESC_FOLHA_PAGTO        AS VALOR_DESCONTO,
                 TO_CHAR(DESC_FOLHA_PAGTO, '0999999D99', 'nls_numeric_characters='',.''') AS VALOR_DESCONTO,
                  CASE 
                       WHEN MB.CLIENT_ID IN ('CANOAS') THEN LPAD('002', 3, '0')  
                       ELSE                                 LPAD('003', 3, '0')
                  END AS COD_FILIAL,
            DECODE(FORMA_PAGTO, '-1', '536', '306') AS FPAGTO                    
                FROM MEMBER MB, V_MOVIMENTACAO VF 
                WHERE MB.MEMBER_ID        = VF.VIDA                       AND
                      MB.CUSTOMER_ID      = VF.COD_PLANO                  AND
                      MB.PERSON_CODE      = VF.PERSON_CODE                AND
                      MB.CLIENT_GROUP_ID  = VF.CLIENT_GROUP_ID            AND
                      MB.CLIENT_ID        = VF.CLIENT_ID                  AND
                      VENDA               = 'S'                           AND
                      STATUS_VENDA        = 'P'                           AND
                      STATUS_FATURAMENTO  = '0'                           AND
                      STATUS_COBRANCA     = '0'                           AND
                      FORMA_PAGTO         = '-1'                          AND                                                                 
                      DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 2 ), VF.CLIENT_GROUP_ID) = DECODE('T','T',DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 2 ), VF.CLIENT_GROUP_ID) ,'T') AND
                      DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 1 ), VF.CLIENT_ID)       = DECODE('T','T',DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 1 ), VF.CLIENT_ID) ,'T') AND                                                     
                      COD_PLANO   =       'CT000224'    AND
                      DATE_FILLED BETWEEN '11-JAN-2010' AND 
                                          '10-FEB-2010'


Porém quando tento executar a query inteira, dá o bendito erro:

Selecionar tudo


SELECT MATRICULA,
       SUM(VALOR_DESCONTO) AS VALOR,      
       COD_FILIAL,
       FPAGTO
FROM(       
    SELECT /*+INDEX(VF V_MOV_PLANO_DATE_FILLED_IDX)*/
                 PATIENT_PIN_NUMBER           AS MATRICULA,  
                 TO_CHAR(DESC_FOLHA_PAGTO, '0999999D99', 'nls_numeric_characters='',.''') AS VALOR_DESCONTO,
                  CASE 
                       WHEN MB.CLIENT_ID IN ('CANOAS') THEN LPAD('002', 3, '0')  
                       ELSE                                 LPAD('003', 3, '0')
                  END AS COD_FILIAL,
            DECODE(FORMA_PAGTO, -1, '536', '306') AS FPAGTO                    
                FROM MEMBER MB, V_MOVIMENTACAO VF 
                WHERE MB.MEMBER_ID        = VF.VIDA                       AND
                      MB.CUSTOMER_ID      = VF.COD_PLANO                  AND
                      MB.PERSON_CODE      = VF.PERSON_CODE                AND
                      MB.CLIENT_GROUP_ID  = VF.CLIENT_GROUP_ID            AND
                      MB.CLIENT_ID        = VF.CLIENT_ID                  AND
                      VENDA               = 'S'                           AND
                      STATUS_VENDA        = 'P'                           AND
                      STATUS_FATURAMENTO  = '0'                           AND
                      STATUS_COBRANCA     = '0'                           AND
                      FORMA_PAGTO         = '-1'                          AND                                                                 
                      DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 2 ), VF.CLIENT_GROUP_ID) = DECODE('T','T',DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 2 ), VF.CLIENT_GROUP_ID) ,'T') AND
                      DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 1 ), VF.CLIENT_ID)       = DECODE('T','T',DECODE(Fu_Get_Empresa_Ativa(VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, VF.VIDA), 'S', Fu_Ret_Client_Group_Atual( VF.VIDA, VF.COD_PLANO, VF.CLIENT_ID, VF.CLIENT_GROUP_ID, 1 ), VF.CLIENT_ID) ,'T') AND                                                     
                      COD_PLANO   =       'CT000224'    AND
                      DATE_FILLED BETWEEN '11-JAN-2010' AND 
                                          '10-FEB-2010') 
                      GROUP BY MATRICULA, COD_FILIAL, FPAGTO

Acho que o erro deve estar em outro lugar e é o que eu estou tentando verificar.

Grato.
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

O seguinte comando retornou o resultado abaixo:

select * from v$version;

Selecionar tudo


 BANNER

Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
PL/SQL Release 9.2.0.1.0 - Production
CORE	9.2.0.1.0	Production
TNS for 32-bit Windows: Version 9.2.0.1.0 - Production
NLSRTL Version 9.2.0.1.0 - Production


Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Então... - o erro não estava no DECODE e sim no TO_CHAR, como segue abaixo:

Selecionar tudo


 DECODE(FORMA_PAGTO, '-1', '536', '306') AS FPAGTO - ok;

 DESC_FOLHA_PAGTO        AS VALOR_DESCONTO,  -- certo
 
TO_CHAR(DESC_FOLHA_PAGTO, '0999999D99', 'nls_numeric_characters='',.''') AS VALOR_DESCONTO, - errado

 
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Sinceramente não entendi a causa do erro uma vez que no teste realizado abaixo, não causou erro algum:

Selecionar tudo


SELECT TO_CHAR(20000, '0999999D99', 'nls_numeric_characters='',.''') FROM DUAL;

Att.
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Na verdade se tornou mais claro depois que eu testei da seguinte maneira:

Selecionar tudo


SELECT TO_CHAR('x', '0999999D99', 'nls_numeric_characters='',.''') FROM DUAL;

Neste caso é gerado o erro "ORA-01722", mas na query original, teoricamente não deveria gerar esse erro, pois o tipo de dado do valor do campo da tabela usado na função é do tipo Number. A minha dúvida é, se tenho que usar um formato fixo para o campo utilizando o TO_CHAR, como vou converter para número um valor onde é esperado caracteres? A impressão que dá a primeira vista é que o Oracle converte o valor do campo da tabela para VARCHAR, porém no momento de aplicar a "máscara" ele ainda é um NUMBER.
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Acho que encontrei o erro, segue abaixo:

Selecionar tudo


SELECT TO_CHAR('1.0', '0999999D99', 'nls_numeric_characters='',.''') FROM DUAL; -- CORRETO 

SELECT TO_CHAR('1,0', '0999999D99', 'nls_numeric_characters='',.''') FROM DUAL; -- ERRADO  
SELECT TO_CHAR(REPLACE('1,0',',','.'), '0999999D99', 'nls_numeric_characters='',.''') FROM DUAL; -- CORRETO

Portanto é correto afirmar que o erro está na vírgula?
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Bacana que deu para encontrar o erro.

Esse código está bem obscuro na minha opinião... fica trocando vírgula por ponto, ponto por vírgula...

Usa REPLACE para ir, depois TO_CHAR para voltar... Típico caso de tartaruga na copa da árvore na minha opinião.

No seu lugar eu tiraria isso tudo. Nessa época de carnaval me ocorre: é só alegoria.
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Graças a ajuda de vocês estou aprendendo bastante, associado a muita leitura. E quanto a confusão do código, vou adaptando conforme eu for aprendendo as boas práticas e mais funcionalidade do Oracle, enquanto isso, fica esse "Spaghetti Code", sei que é feio e pretendo melhorar.

É que na verdade simplesmente, preciso pegar um número absoluto e aplicar uma máscara de "moeda", existe algum modo mais "elegante" ou correto de se fazer isso?

Olhando melhor consegui fazer desta maneira:

Selecionar tudo


TO_CHAR(ABS(vTST_CURSOR2.VALOR), '0999999D99', 'nls_numeric_characters='',.''')

 
Parece ter ficado um pouco melhor com o uso do "ABS".

Att.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Não entendi, por que o ABS? Você quer que todos valores sejam mostrados positivos? O ABS é função de módulo, só vai tirar o sinal negativo.

Se você quer colocar formato para moeda é só colocar L na frente da máscara de formato.

Selecionar tudo

SQL> select to_char(1500.9, 'L0G000G000D00', 'NLS_NUMERIC_CHARACTERS = '',.'' NLS_CURRENCY=''R$''') from dual;
 
TO_CHAR(1500.9,'L0G000G000D00'
------------------------------
         R$0.001.500,90
 
SQL> 
O NLS_CURRENCY é para especificar qual a sigla que você quer usar como sua moeda. Se não for Real é só trocar para o símbolo do Dólar ou Euro, ou qualquer coisa que quiser.
Desculpe se entendi mal o que você precisa.
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

É isso mesmo eu preciso exibir o valor sem o sinal de negativo, por isso usei o ABS, para que o número se enquadre na quantidade de caracteres definidos no layout do arquivo texto. E quanto ao formato da moeda, o cliente havia especificado que precisava que no layout o valor você impresso sem os separadores de milhar e utilizasse vírgula para separar os decimais (parece obvio, mas já me pediram outras coisas "esquisitas"), por isso estou utilizando o seguinte formato:

Selecionar tudo


'0999999D99', 'nls_numeric_characters='',.''

 Sem cifrão (R$).

Um pequeno exemplo do arquivo texto gerado:

Selecionar tudo


03028/02/2010003
3128245360000088,33
3135255360000019,12
3135643060000045,20

Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Saquei, a solução que você postou já está atendendo bem então.

Esses negócios para gerar arquivo com campo de largura fixa às vezes vai até sem vírgula nem ponto também. Duas casas decimais concatenadas só... cada um tem uma regra. :roll:

Falou
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

É isso aê! Agora está tudo ok...

Muito obrigado.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 20 visitantes