- Este tópico contém 3 respostas, 2 vozes e foi atualizado pela última vez 8 anos, 2 meses atrás por José Laurindo Chiappa.
-
AutorPosts
-
20 de setembro de 2016 às 3:49 pm #108418acg1574Participante
Pessoal, estou com um grande problema, preciso executar varios selects, e esses selects vem de um script, para cada linha do cursor é um select a ser executado e preciso guardar o conteudo de cada select em um arquivo texto, preciso saber como trabalhar com um cursor que me monta um script de selects, nao esta dando certo, vou passar o codigo para voces.
seria mais ou menos isso, se alguem puder me ajudar agradeço.
create or replace PROCEDURE PRC_SCRIPT_SX3_SXB
ASarquivo_saida UTL_File.File_Type;
CURSOR cTabelas
IS
SELECT XB_ALIAS aliass,trim(X3_ARQ) arq,X3_CAMPO campo,x3_tabela tabela FROM SXB,SX3
WHERE
XB_TIPO=’1′
AND (XB_CONTEM LIKE ‘%CTT%’ OR XB_CONTEM LIKE ‘%CT1%’ OR XB_CONTEM LIKE ‘%CTD%’ OR XB_CONTEM LIKE ‘%CTH%’)
AND XB_ALIAS=X3_F3
ORDER BY X3_ARQ,XB_ALIAS,X3_CAMPO;BEGIN
arquivo_saida := UTL_File.Fopen(‘/backup/oracle/output’,’sx3sxb.txt’, ‘W’);FOR rTabelas IN cTabelas
LOOPfor cScript in(
select ‘ DISTINCT ‘ || ”” || TRIM(SX3.X3_CAMPO) || ”’ CAMPO,”’ || SX3.X3_ARQ || ‘010” TABELA, ‘ || SX3.X3_CAMPO || ‘ CONTEUDO FROM TOTVS.’ || SX3.X3_ARQ || ‘010’ consulta FROM SXB ,SX3
–SELECT DISTINCT TRIM(SX3.X3_CAMPO) CAMPO,SX3.X3_TABELA TABELA,TRIM(SX3.X3_CAMPO) CONTEUDO FROM SXB ,SX3
WHERE
XB_TIPO=’1′
AND (XB_CONTEM LIKE ‘%CTT%’ OR XB_CONTEM LIKE ‘%CT1%’ OR XB_CONTEM LIKE ‘%CTD%’ OR XB_CONTEM LIKE ‘%CTH%’)
AND XB_ALIAS=X3_F3 AND X3_ARQ=rTabelas.arq
ORDER BY X3_TABELA,X3_CAMPO)
loopfor cScript in cTabelas
loop
UTL_File.Put_Line(arquivo_saida,cScript.campo);
–EXIT WHEN r%NOTFOUND;end loop;
end loop;
UTL_File.Put_Line(arquivo_saida, rTabelas.aliass || rTabelas.tabela || rTabelas.campo);
END LOOP;UTL_File.Fclose(arquivo_saida);
Dbms_Output.Put_Line(‘Arquivo gerado com sucesso.’);EXCEPTION
WHEN UTL_FILE.INVALID_OPERATION THEN
Dbms_Output.Put_Line(‘Operação inválida no arquivo.’);
UTL_File.Fclose(arquivo_saida);
WHEN UTL_FILE.WRITE_ERROR THEN
Dbms_Output.Put_Line(‘Erro de gravação no arquivo.’);
UTL_File.Fclose(arquivo_saida);
WHEN UTL_FILE.INVALID_PATH THEN
Dbms_Output.Put_Line(‘Diretório inválido.’);
UTL_File.Fclose(arquivo_saida);
WHEN UTL_FILE.INVALID_MODE THEN
Dbms_Output.Put_Line(‘Modo de acesso inválido.’);
UTL_File.Fclose(arquivo_saida);
WHEN OTHERS THEN
Dbms_Output.Put_Line(‘Problemas na geração do arquivo.’);
UTL_File.Fclose(arquivo_saida);
END PRC_SCRIPT_SX3_SXB;20 de setembro de 2016 às 3:50 pm #108419acg1574Participanteele nao reconhece os campos do cursor cScript q no caso é montado atraves de um script, obrigado.
20 de setembro de 2016 às 4:33 pm #108420acg1574Participantetentei assim tambem, criei um arquivo com todos os select , mas ele nao aceita a sintaxe de for cScript in (linha)
BEGIN
arquivo_saida := UTL_File.Fopen(‘/backup/oracle/output’,’sx3sxb.txt’, ‘W’);arquivo_ler := UTL_File.Fopen('/backup/oracle/output','tabelas_sxs.txt', 'r'); Loop UTL_File.Get_Line(arquivo_ler, Linha); for cScript in (Linha) loop UTL_File.Put_Line(arquivo_saida,linha); end loop; End Loop; UTL_File.Fclose(arquivo_ler); UTL_File.Fclose(arquivo_saida);
20 de setembro de 2016 às 6:00 pm #108421José Laurindo ChiappaModeradorBem, eu vejo umas besteiradas nesse código : por exemplo, numa parte dele vc faz :
…
for cScript in(
select ‘ DISTINCT ‘ || ”” || TRIM(SX
.loop…e depois, DENTRO DESSE LOOP ainda, vc pede :
…
for cScript in cTabelasloop
UTL_File.Put_Line….==> OU SEJA, além de usar a ** mesma ** variável do tipo record CSCRIPT duas vezes em for loops diferentes e concatenados (o que é *** PROIBIDO !!! ***), sinceramente não entendi o que vc quer abrindo ** TRÊS ** loops no total : ao que entendo, o que vc quer é simplesmente UM LOOP, abrindo o Cursor cTabelas, o acionando até o final (num LOOP só) e dentro desse LOOP Gravar cada linha retornada , só isso….
O ponto ** principal ** que eu TENHO que te avisar, porém, é algo que está PLENAMENTE DOCUMENTADO nos manuais PL/SQL : a linguagem PL/SQL só pode executar SQLs que ** OU ** estão fixos e diretamente explicitados entre blocos BEGIN/END , ** OU ** então pode executar SQLs dinâmicos através de cláusulas EXECUTE IMMEDIATE ‘stringdoSQL’ ou via package DBMS_SQL – a linguagem NÃO TEM COMO executar código SQL dinâmico/não fixo que está em arquivos-texto (que seriam os scripts, pelo que vejo)…. okdoc ?? Isso é Conceitual, ela Não TEM recurso nativo pra isso, pode Conferir nos manuais de PL/SQL e na Documentaçaõ Oracle …
Suas alternativas então para fazer como vc quer (ie, gerando arquivo com os comandos e depois “executar” esse arquivo) seriam :
a) ter um shell script que conecte no sqlplus, execute a procedure de geração do arquivo-texto de scripts e depois ainda dentro do sqlplus execute com @ esse arquivo de scripts gerado – isso é imho a mais simples mas vc TEM que tomar o cuidado de seguir a sintaxe de scripts do sqlplus, tendo ; após cada comando e adotando extensão .SQL no arquivo-texto, por exemplo…
ou
b) na própria procedure, depois que vc gerou o arquivo de script com os comandos, vc ABRE esse arquivo gerado, lê os comandos e executa cada um via EXECUTE IMMEDIATE – isso é relativamente COMPLEXO de se fazer e vc parece não ter muita experiência com programação PL/SQL então não recomendo esse caminho mas é Possível…
==>>> OBVIAMENTE, porém, eu tenho que apontar : SE os comandos SQL a serem executados estão nessas tabelas aí que vc mostra no cursor , *** PRA QUÊ *** vc está se preocupando em gerar arquivo-texto com eles, vc não pode simplesmente os ler num LOOP e EXECUTAR via EXECUTE IMMEDIATE ou DBMS_SQL cada comando lido ? AVALIE essa possibilidade…
Sendo assim eu recomendo que Plz dê uma ** limpada ** decente nesse código, Corrija os erros evidentes e depois de Feito isso, se vc ainda tiver problemas manda pra gente o CREATE TABLE e uns INSERTs populando as tais tabelas que a gente pode tentar reproduzir teu código Limpo e palpitar em cima….
[]s
Chiappa
-
AutorPosts
- Você deve fazer login para responder a este tópico.