Ler txt com várias linhas e salvar em um cursor

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
jorgespbr
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Sex, 04 Jan 2008 7:52 am
Localização: SP
O importante não é saber e sim conhecer quem sabe.

Boa tarde,

Preciso ler um arquivo txt com aprox. 7k linhas e salvar em um cursor para posteriormente usar este curso em um UPDATE, alguém pode me ajudar ou dar alguma dica.

Obrigado
Tineks
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 365
Registrado em: Ter, 24 Mai 2005 2:24 pm
Localização: Araraquara - SP
Cristiano (Tineks)
Araraquara - SP

E ai Jorge, tudo beleza??

cara, você não poderia já fazer o update conforme vai lendo as linhas do arquivo??

[]'s
jorgespbr
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Sex, 04 Jan 2008 7:52 am
Localização: SP
O importante não é saber e sim conhecer quem sabe.

Seria uma opção.
O arquivo txt contem os ID's de clientes onde tenho que ler o ID e jogar algumas informações deste cliente em outra tabela. Mas isso seria para um número aproximado de 7k clientes.

Grato
Tineks
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 365
Registrado em: Ter, 24 Mai 2005 2:24 pm
Localização: Araraquara - SP
Cristiano (Tineks)
Araraquara - SP

De inicio você tinha perguntado se dava pra jogar dentro de um cursor, uma opção seria jogar os dados dentro de uma tabela temporária, e depois fazer um loop atualizando esses registros, aqui nesse link tem esse processo mais detalhado...

qualquer dúvida é só falar.

[]'s!!
jorgespbr
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Sex, 04 Jan 2008 7:52 am
Localização: SP
O importante não é saber e sim conhecer quem sabe.

Obrigado Cristiano, realmente não sabia por onde começar, é a primeira vez que trabalho com UTL_FILE e com CURSOR....mas acho que deu pra quebrar o galho. Tem alguns DBMS q estava usando pra testar...
Fique a vontade para dar sugestões
Obrigado

Segue o código

Selecionar tudo

DECLARE
    arquivo_ler                 UTL_File.File_Type;
    Linha                       varchar2(3000);
	p_diretorio        			varchar2(200) := 'diretorio';
    cursor c is
                SELECT rc.customer_id, ra.address_id
                        ,ra.GLOBAL_ATTRIBUTE3||ra.GLOBAL_ATTRIBUTE4||ra.GLOBAL_ATTRIBUTE5 CNPJ
                        ,ra.attribute1
                FROM    ra_customers rc, ra_addresses_all ra
                Where   rc.customer_id = ra.customer_id
                and     rc.customer_number = replace(Linha, chr(13),'');
    c_rc_id       ra_customers.customer_id%TYPE;
    c_ra_id       ra_addresses_all.address_id%TYPE;
    c_cnpj        varchar2(500);
    c_mail        ra_addresses_all.attribute1%TYPE;
	BEGIN
		arquivo_ler := UTL_File.Fopen(p_diretorio,'clienteste.txt', 'R');
		LOOP
            UTL_File.Get_Line(arquivo_ler, Linha);
            open c;
            dbms_output.put_line('recuperando informação do cursor');
            fetch c into c_rc_id, c_ra_id, c_cnpj, c_mail;
            dbms_output.put_line(c_rc_id||':'||c_ra_id||':'||c_cnpj||':'||c_mail);
            dbms_output.put_line('Inserindo na tabela');
            
            Insert into off_brindes
                values (22,                                         --org_id
                        c_rc_id,                                    --customer_id
                        c_ra_id,                                    --address_id
                        null,                                       --status
                        '1',                                        --brinde
                        nvl(c_cnpj, 'inexistente'),                 --cnpj
                        nvl(c_mail, 'sem email'),                   --email
                        null,                                       --dta_atendimento
                        sysdate,                                    --creation_date
                        64,                                         --created_by
                        sysdate,                                    --last_update_date
                        64,                                         --last_updated_by
                        'Teste de cadastro');                       --motivo
    close c;    	
    END LOOP;
    UTL_File.Fclose(arquivo_ler);

	EXCEPTION
	    WHEN No_data_found THEN
	               UTL_File.Fclose(arquivo_ler);
	               Commit;
	    WHEN UTL_FILE.INVALID_PATH THEN
	               Dbms_Output.Put_Line('Diretório inválido.');
	               UTL_File.Fclose(arquivo_ler);
	    WHEN UTL_FILE.READ_ERROR THEN
			      DBMS_OUTPUT.PUT_LINE('Erro durante a leitura.');
			      UTL_FILE.FCLOSE(arquivo_ler);
	    WHEN UTL_FILE.INVALID_MODE THEN
	               Dbms_Output.Put_Line('Modo de acesso inválido.');
	               UTL_File.Fclose(arquivo_ler);
	    WHEN UTL_FILE.INVALID_OPERATION THEN
	               Dbms_Output.Put_Line('O arquivo não pode ser aberto ou a operação é inválida.');
	               UTL_File.Fclose(arquivo_ler);
	    WHEN UTL_FILE.INTERNAL_ERROR THEN
	                Dbms_Output.Put_Line('Erro não especificado');
	               UTL_File.Fclose(arquivo_ler);
	    WHEN Others THEN
	               Dbms_Output.Put_Line ('Outros Erros.'||sqlerrm);
	               UTL_File.Fclose(arquivo_ler);
END;
Tineks
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 365
Registrado em: Ter, 24 Mai 2005 2:24 pm
Localização: Araraquara - SP
Cristiano (Tineks)
Araraquara - SP

Jorge,

durante o processo de inclusão, se der erro em algum registro você quer continuar a incluir o proximo ou para todo o processo?

um costume que eu tenho é nesses casos fazer o commit dos registros a cada 500, 1000, dependendo da tabela ou do processo..

[]'s
jorgespbr
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Sex, 04 Jan 2008 7:52 am
Localização: SP
O importante não é saber e sim conhecer quem sabe.

Num sei, acho difícil dar erro pois sei que a informação do txt sempre vai existir. Mas sim, caso de algum erro em uma das inserções, seria legal ele continuar com as demais mas guardar uma informação daquele que teve erro, num sei, talvez num arquivo de log. Mas ainda não estou tão caraque assim, é a primeira vez que crio uma instrução PL/SQL, geralmente apenas verifico as informações do banco fazendo Select, já que não tenho acesso a UPDATE, DELETE ou algum comando que possa prejudicar a produção ou interferir com a consistencia do banco, apenas faço isso no ambiente de desenvolvimento.
cron_rj
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 25
Registrado em: Qua, 19 Dez 2007 9:10 am
Localização: Rio de Janeiro RJ

Achei um exemplo aqui da minha fase de estudos, mas é do arquivo para um insert na tabela. Você pode alterar e implementar para um cursor. O pacote para essas operações que uso é o TEXT_IO.

Selecionar tudo

PROCEDURE PRC_ARQ_P_TAB IS
BEGIN
    DECLARE    
        l_origem TEXT_IO.FILE_TYPE;  -- Cria um tipo para o arquivo de origem
        registro VARCHAR2(110);      -- Variável que representa a linha do arquivo
    BEGIN    
        l_origem:= TEXT_IO.FOPEN('c:\func_fred.txt','w'); -- Associa o arquivo a variável       
        LOOP  --Inicia o loop
            TEXT_IO.GET_LINE(l_origem,registro);  -- Atribui a linha corrente a variável registro          
            INSERT INTO func_fred2 (mat_func,    -- number(4)
                                    nm_func,     -- varchar2(35)
                                    sb_func,     -- varchar2(35)
                                    dt_admissao, -- date
                                    cargo,       -- number(2)
                                    salario,     -- number(8,2)
                                    funcao       -- varchar2(25) 
                                   )
                           VALUES (
                                TO_NUMBER((SUBSTR(registro,                        -- Linha (mat_func)
                                (INSTR(SUBSTR(registro,1,110),';',1,1) +1 ),       -- Pos. Inicial 
                                (INSTR(SUBSTR(registro,1,110),';',1,2) -2 )))),    -- Pos. Final  
                                
                                (SUBSTR(registro,                                 
                                (INSTR(SUBSTR(registro,1,110),';',1,2) +1 ),       -- (nm_func)
                                (INSTR(SUBSTR(registro,1,110),';',1,3)) -        
                                (INSTR(SUBSTR(registro,1,110),';',1,2) +1 )
                                )),     
                                
                                (SUBSTR(registro,                                 
                                (INSTR(SUBSTR(registro,1,110),';',1,3) +1 ),      -- (sb_func)
                                (INSTR(SUBSTR(registro,1,110),';',1,4)) -
                                (INSTR(SUBSTR(registro,1,110),';',1,3) +1 )
                                )),                                                
                                
                                TO_DATE((SUBSTR(registro,                        -- (dt_admissao)         
                                (INSTR(SUBSTR(registro,1,110),';',1,4) +1 ),      
                                (INSTR(SUBSTR(registro,1,110),';',1,5)) -
                                (INSTR(SUBSTR(registro,1,110),';',1,4) +1 )
                                )),'dd/mm/yyyy'),         
                                
                                TO_NUMBER((SUBSTR(registro,                      -- (cargo) 
                                (INSTR(SUBSTR(registro,1,110),';',1,5) +1 ),      
                                (INSTR(SUBSTR(registro,1,110),';',1,6)) -
                                (INSTR(SUBSTR(registro,1,110),';',1,5) +1 )
                                )),'99'),
                                
                                TO_NUMBER((SUBSTR(registro,                      -- (salario) 
                                (INSTR(SUBSTR(registro,1,110),';',1,6) +1 ),      
                                (INSTR(SUBSTR(registro,1,110),';',1,7)) -
                                (INSTR(SUBSTR(registro,1,110),';',1,6) +1 )
                                )),'999,999,99'),
                                
                                (SUBSTR(registro,                                 
                                (INSTR(SUBSTR(registro,1,110),';',1,7) +1 ),      -- (funcao)
                                (INSTR(SUBSTR(registro,1,110),';',1,8)) -
                                (INSTR(SUBSTR(registro,1,110),';',1,7) +1 )
                                ))   
                                
                                );  -- Fim dos values                      
                                                         

                                 
        END LOOP;  -- Fim do Loop       
        EXCEPTION 
        WHEN NO_DATA_FOUND THEN 
           COMMIT; 
           TEXT_IO.FCLOSE(l_origem); -- Fecha o arquivo
    END; 
END;
jorgespbr
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Sex, 04 Jan 2008 7:52 am
Localização: SP
O importante não é saber e sim conhecer quem sabe.

Bme parecido com o UTL_FILE, obrigado pela ajuda, vou guarda esse código. Apesar de ser uma sexta tem bastante coisa pra acabar aqui.
Bom fim de semana.
Responder
  • Informação