- Este tópico contém 8 respostas, 4 vozes e foi atualizado pela última vez 7 anos, 10 meses atrás por ysmaylyka soares macedo.
-
AutorPosts
-
8 de fevereiro de 2017 às 11:01 pm #108623ysmaylyka soares macedoParticipante
create or replace procedure SP_EXP_TXT_RESTORE_DMAE is
/****************************************************************
* PROCEDURE : SP_EXP_TXT_RESTORE_DMAE *
* OBJETIVO : Exporta dados de uma tabela para um arquivo texto *
* CRIACAO : 07/02/2017 *
* VERSAO : 1.0 *
* AUTOR : YSMAYLYKA SOARES MACEDO – *
****************************************************************/—————————————————–
— DECLARACAO DE VARIAVEIS P/ CONTROLE DO PROCESSO —
—————————————————–
ARQ_NRSORTE UTL_FILE.file_type;
VC_LINHA VARCHAR2(8000) := NULL;
VC_ARQ_NOME VARCHAR2(100) := NULL;
VC_DIR_LOG VARCHAR2(50) := ‘/home/oracle/log’;
VC_DIR_OUT VARCHAR2(50) := ‘/home/oracle/log_out’;
VG_PROCESSO VARCHAR2(100) := ‘RESTORE DMAE’;————————————
— CURSOR PARA GERACAO DO ARQUIVO —
————————————
CURSOR CUR_INSTANCE IS
SELECT
INSTANCE_NAME ,
STARTUP_TIME ,
ARCHIVER ,
DATABASE_STATUS
FROM V$INSTANCE;begin
———————
— BUSCA DIRETORIO —
———————
/*
BEGIN
SELECT PINT_NM_DIRETORIO_LOG, PINT_NM_DIRETORIO_OUT
INTO VC_DIR_LOG, VC_DIR_OUT
FROM GEMCO_PARAMETRO_INTERFACE PINT, GEMCO_SISTEMA SIST
WHERE PINT.PINT_CD_SISTEMA = SIST.SIST_CD_SISTEMA
AND SIST.SIST_DS_SISTEMA = VG_PROCESSO;
EXCEPTION
— SE NAO EXISTIR INFORMAR O DIRETORIO ONDE DEVERA SER
— GERADO O LOG DE OCORRENCIAS
WHEN NO_DATA_FOUND THEN
VC_DIR_LOG := ‘/home/gemco/integra/Log’;
VC_DIR_OUT := ‘/home/gemco/integra/Gemco-Legado’;
WHEN TOO_MANY_ROWS THEN
VC_DIR_LOG := ‘/home/gemco/integra/Log’;
VC_DIR_OUT := ‘/home/gemco/integra/Gemco-Legado’;
WHEN OTHERS THEN
VC_DIR_LOG := ‘/home/gemco/integra/Log’;
VC_DIR_OUT := ‘/home/gemco/integra/Gemco-Legado’;
END;
*/— SETA NOME DO ARQUIVO
VC_ARQ_NOME := ‘RESTORE DMAE ‘ || TO_CHAR(SYSDATE, ‘DD/MM/RRRR HH24:MI:SS’) || ‘.txt’;
— INICIA GRAVACAO
ARQ_NRSORTE := UTL_FILE.fopen(VC_DIR_OUT, VC_ARQ_NOME, ‘W’);
UTL_FILE.fclose(ARQ_NRSORTE);—————————————–
— ABRE CURSOR PARA LEITURA E MONTAGEM —
—————————————–
FOR CUR IN CUR_INSTANCE LOOP
VC_LINHA := LPAD(CUR.INSTANCE_NAME, 5, 0) || ‘;’ ||
TO_CHAR(CUR.STARTUP_TIME, ‘DD/MM/RRRR HH24:MI:SS’) || ‘;’ ||
LPAD(CUR.ARCHIVER, 11, 0) || ‘;’ ||
LPAD(CUR.DATABASE_STATUS, 10, ‘ ‘) ;— GRAVA O REGISTRO NO ARQUIVO
ARQ_NRSORTE := UTL_FILE.fopen(VC_DIR_OUT, VC_ARQ_NOME, ‘A’);
UTL_FILE.put_line(ARQ_NRSORTE, VC_LINHA);
UTL_FILE.fclose(ARQ_NRSORTE);
END LOOP;EXCEPTION
WHEN UTL_FILE.INVALID_PATH THEN
dbms_output.put_line(‘ERRO: INVALID PATH – ‘ || SQLCODE || ‘ ‘ ||
SQLERRM);
WHEN UTL_FILE.INVALID_MODE THEN
dbms_output.put_line(‘ERRO: FILE ‘ || VC_DIR_LOG || ‘ / ‘ ||
VC_DIR_OUT || ‘ INVALID MODE – ‘ || SQLCODE || ‘ ‘ ||
SQLERRM);
WHEN UTL_FILE.INVALID_OPERATION THEN
dbms_output.put_line(‘ERRO: FILE ‘ || VC_DIR_LOG || ‘ / ‘ ||
VC_DIR_OUT || ‘ INVALID OPERATION – ‘ || SQLCODE || ‘ ‘ ||
SQLERRM);
WHEN UTL_FILE.INVALID_FILEHANDLE THEN
RAISE_APPLICATION_ERROR(-20902, SQLCODE || ‘ ‘ || SQLERRM);
WHEN UTL_FILE.INTERNAL_ERROR THEN
dbms_output.put_line(‘ERRO: INTERNAL ERROR – ‘ || SQLCODE || ‘ ‘ ||
SQLERRM);
WHEN UTL_FILE.READ_ERROR THEN
dbms_output.put_line(‘ERRO: READ ERROR – ‘ || SQLCODE || ‘ ‘ ||
SQLERRM);
WHEN UTL_FILE.WRITE_ERROR THEN
dbms_output.put_line(‘ERRO: WRITE ERROR – ‘ || SQLCODE || ‘ ‘ ||
SQLERRM);
WHEN VALUE_ERROR THEN
dbms_output.put_line(‘ERRO: VALUE ERROR – ‘ || SQLCODE || ‘ ‘ ||
SQLERRM);
WHEN OTHERS THEN
dbms_output.put_line(SQLCODE || ‘ ‘ || SQLERRM);end ;
/A procedure não estar enviando o arquivo para pasta.
9 de fevereiro de 2017 às 3:44 pm #108624spernegaParticipanteBom dia,
É só um palpite…
tente gerar o nome do arquivo sem / e :
‘RESTORE DMAE ‘ || TO_CHAR(SYSDATE, ‘DD/MM/RRRR HH24:MI:SS’) || ‘.txt’;‘RESTORE DMAE ‘ || TO_CHAR(SYSDATE, ‘DD-MM-RRRR HH24-MI-SS’) || ‘.txt’;
9 de fevereiro de 2017 às 5:03 pm #108625José Laurindo ChiappaModeradorBem, fica ** extremamente ** difícil se debugar um código grande (e nem é esse o objetivo aqui do Fórum, a nossa intenção aqui é fornecer Guias gerais, princiípios e ajudinhas, e NÃO fazer programação e/ou debug de código extraído da Produção – pelo menos vc devria ter nos dado é um Código PEQUENO e ENXUTO demonstrando o princípio geral do que vc quer fazer – e com os CREATE TABLEs e uns INSERTs pra gente reproduzir!!!) mas numa passada de olhos vi um trecho Absolutamente sem sentido :
….
ARQ_NRSORTE := UTL_FILE.fopen(VC_DIR_OUT, VC_ARQ_NOME, ‘W’);
UTL_FILE.fclose(ARQ_NRSORTE);
…==>> OU SEJA, vc abriu e logo em seguida Fechou o arquivo ???? Issso não faz sentido nenhum, vc via de regra primeiro ABRE, depois grava cada linha e só Fecha depois que gravou tudo…
[]s
Chiappa
9 de fevereiro de 2017 às 5:14 pm #108626airoospParticipanteBom dia,
Fiz um teste aqui com a procedure que você passou, funcionou mas tive que fazer a seguinte alteração:
— INICIA GRAVACAO
ARQ_NRSORTE := UTL_FILE.fopen(VC_DIR_OUT, VC_ARQ_NOME, ‘W’);— INICIA GRAVACAO
ARQ_NRSORTE := UTL_FILE.fopen(‘GRAVACAO’, VC_ARQ_NOME, ‘W’);Esse GRAVACAO é um diretório criado no banco que aponta para um caminho no servidor, para criar é necessário estar logado como SYS e executar:
CREATE DIRECTORY GRAVACAO AS ‘c:arquivos’;
GRANT READ WRITE ON DIRECTORY GRAVACAO TO usuario que executa procedure;
Você precisará substituir VC_DIR_OUT por ‘GRAVACAO’ em todas as linhas que aparece o VC_DIR_OUT.
Abraço,
Airton
10 de fevereiro de 2017 às 1:34 am #108627José Laurindo ChiappaModeradorSim, além das eventuais questões de lógica (como o OPEN imediatemente seguido do CLOSE), que Não tenho como saber se estão presentes no resultado final já que não tenha as tabelas e dados pra tentar reproduzir (a colega Não Nos deu nada), é verdade que a Recomendação para vc indicar o PATH aonde o UTL_FILE vai fazer I/O é se criar um objeto do tipo DIRECTORY dentro do banco : não é o único, a lógica da colega de passar uma string com o path Até Poderia funcionar desde que o path esteja contido no parãmetro UTL_FILE_DIR, esse era o mecanismo antigamente…. Como esse parâmetro UTL_FILE_DIR é ** interno ** ao database normalmente só o DBA pode mexer nele (desenvolvedores, como suponho ser a colega, não tem acesso a internals de banco), então via de regra é mais prático se usar o DIRECTORY…
Só discordo ** VEEMENTEMENTE ** quando vc recomenda criar o DIRECTORY no schema do SYS : o SYS é ** especial **, é um schema/usuário RESTRITO, que possui os objetos criados pela própria Oracle para o funcinamento interno do RDBMS, é ABSOLUTAMENTE e TOTALMENTE PROBIDO PELA ORACLE de criarmos objetos nossos no usuário/schema SYS : veja o que diz a documentação Oracle :”
SYS and SYSTEM Schemas
All Oracle databases include default administrative accounts. Administrative accounts are highly privileged and are intended only for DBAs authorized to perform tasks such as starting and stopping the database, managing memory and storage, creating and managing database users, and so on.
The administrative account SYS is automatically created when a database is created. This account can perform all database administrative functions. The SYS schema stores the base tables and views for the data dictionary. These base tables and views are critical for the operation of Oracle Database. Tables in the SYS schema are manipulated only by the database and must never be modified by any user.
”e dá também uma olhada nas refs dos gurus que repetem o mesmo, como http://www.adp-gmbh.ch/ora/misc/sys_system_internal.html, https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:1562813956388 e http://oracle-randolf.blogspot.com.br/2009/05/user-objects-created-in-sys-schema-and.html se precisar de ainda mais argumentos contra essa prática de criar objetos seus nos chema SYS (ou manipular de QUALQUER FORMA o schema SYS)…
[]s
Chiappa
10 de fevereiro de 2017 às 1:59 pm #108629spernegaParticipanteFiz mais um teste, a rotina parece estar correta mas tive que usar o DIRECTORY_NAME ao invés do DIRECTORY_PATH para as variáveis vc_dir_log e vc_dir_out.
Testei com um usuário normal do meu sistema, consequentemente não consegui usar a query V$INSTANE, substitui por uma tabela do meu usuário, funcionou.
10 de fevereiro de 2017 às 5:47 pm #108630airoospParticipanteUtilizando o código que a colega postou e fazendo pequenas alterações, o arquivo foi gerado. Como o teste foi feito em ambiente de homologação, criei uma view da v$instance para mostrar apenas os campos necessários, e atribui para o usuário utilizado no teste, a permissão de select nesta view.
O usuário SYS foi citado anteriormente como exemplo para criação do diretório, mas o diretório pode ser criado por um usuário que tenha permissão para isso, e depois atribuir as permissões read e write para o usuário que vai executar a procedure.
O que foi alterado:
CURSOR CUR_INSTANCE IS
SELECT INSTANCE_NAME, STARTUP_TIME, ARCHIVER, DATABASE_STATUS
FROM vw_instance;— INICIA GRAVACAO
ARQ_NRSORTE := UTL_FILE.fopen(‘ARQUIVOS’, VC_ARQ_NOME, ‘W’);
UTL_FILE.fclose(ARQ_NRSORTE);
— ABRE CURSOR PARA LEITURA E MONTAGEM —
FOR CUR IN CUR_INSTANCE LOOP
VC_LINHA := LPAD(CUR.INSTANCE_NAME, 5, 0) || ‘;’ ||
TO_CHAR(CUR.STARTUP_TIME, ‘DD/MM/RRRR HH24:MI:SS’) || ‘;’ ||
LPAD(CUR.ARCHIVER, 11, 0) || ‘;’ ||
LPAD(CUR.DATABASE_STATUS, 10, ‘ ‘);-- GRAVA O REGISTRO NO ARQUIVO ARQ_NRSORTE := UTL_FILE.fopen('ARQUIVOS', VC_ARQ_NOME, 'A'); UTL_FILE.put_line(ARQ_NRSORTE, VC_LINHA); UTL_FILE.fclose(ARQ_NRSORTE);
Onde ARQUIVOS é o directory que foi criado.
10 de fevereiro de 2017 às 5:50 pm #108631José Laurindo ChiappaModeradorYep, spernega, o colega airoosp já tinha em msg anterior apontado que conseguiu executar o tal código : inclusive, como a colega Não nos forneceu as tabelas envolvidas, Suponho que sejam de algum Aplicativo de terceiros que casualmente ambos tenham instalado/sejam usuários…. Como não tenho as tais tabelas, não posso/sei Avaliar isso…
Bom, como eu disse Sim, tecnicamente o UTL_FILE pode mesmo funcionar criando um objeto do tipo DIRECTORY apontando pra pasta/diretório/caminho de destino ** MAS ** sim, funciona também apontando numa string o path/diretório completo, desde que esse diretório/path esteja incluído no parâmetro UTL_FILE_DIR do seu banco…EM face desses dois reports de sucesso em outros bancos mas (imagino) com o mesmo aplicativo e mesmas tabelas que vc usa, Ysmaylyka , o que eu recomendo pra vc é fazer um debug no seu código (pode ser simplesmente colocando uns DBMS_OUTPUT pra ver se o programa tá chegando nas linhas de código que fazem a gravação) E também executar manualmente a consulta dos cursores (pra verificar se casualmente o seu problema é que, com os seus dados, o cursor não tá achando registros e por isso não tá gravando no arquivo)…
[]s
Chiappa
22 de fevereiro de 2017 às 6:01 pm #108635ysmaylyka soares macedoParticipanteObrigado pelas respostas pessoal!
Vou fazer alguns testes. -
AutorPosts
- Você deve fazer login para responder a este tópico.