[oracle_br] Tabela temporária

2020-01-23 Por tôpico Clodoaldo Vilela clodoaldovil...@yahoo.com.br [oracle_br]
Alguém tem um exemplo de criação e manipulação de tabela temporária dentro de 
uma procedure?

RES: [oracle_br] Re: RES: RES: [oracle_b r] Re: Tabela Vári avel

2019-02-19 Por tôpico 'Clodoaldo Vilela' clodoaldovil...@yahoo.com.br [oracle_br]
Muito obrigado

 

De: oracle_br@yahoogrupos.com.br [mailto:oracle_br@yahoogrupos.com.br] 
Enviada em: segunda-feira, 18 de fevereiro de 2019 16:29
Para: oracle_br@yahoogrupos.com.br
Assunto: [oracle_br] Re: RES: RES: [oracle_b r] Re: Tabela Vári avel

 

  

Pra não ficar só no blablablá, eis um exemplo (basicamente COPIADO e COLADO dos 
links que te dei) duma rotina PL/SQL que executa um SQL sem saber nem o npme da 
tabela nem a quantidade de colunas e seus datatypes) - logicamente, aqui eu só 
Exibo via DBMS_OUTPUT, mas vc pode fazer o que bem quiser com os dados qye 
recuperar :

scott@DESENV:SQL>set serveroutput on size 100
scott@DESENV:SQL>create or replace procedure PRINT_QUERY_COLUMNS (P_SQL 
varchar2) is
  2v_SQL VARCHAR2(32767);
  3v_c  NUMBER;
  4v_executeNUMBER;
  5v_columnCount INTEGER;
  6v_recTab  DBMS_SQL.DESC_TAB;
  7v_varcharVal  VARCHAR2(4000);
  8v_numberVal  NUMBER;
  9v_dateValDATE;
 10v_retNUMBER;  
 11  BEGIN
 12v_sql := P_SQL; -- Exemplo : 'select * from employees where rownum=1'
 13v_c := DBMS_SQL.OPEN_CURSOR;
 14
 15DBMS_SQL.PARSE(v_c, v_SQL, DBMS_SQL.NATIVE);
 16
 17v_execute := DBMS_SQL.EXECUTE(v_c);
 18
 19DBMS_SQL.DESCRIBE_COLUMNS(v_c, v_columnCount, v_recTab);
 20
 21FOR j in 1..v_columnCount
 22  
 23  LOOP
 24CASE v_recTab(j).col_type
 25  WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(v_c,j,v_varcharVal,2000);
 26  WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(v_c,j,v_numberVal);
 27  WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(v_c,j,v_dateVal);
 28  ELSE DBMS_SQL.DEFINE_COLUMN(v_c,j,v_varcharVal,2000);
 29END CASE;
 30  END LOOP;
 31  
 32  LOOP
 33v_ret := DBMS_SQL.FETCH_ROWS(v_c);
 34  EXIT WHEN v_ret = 0;
 35  
 36  FOR j in 1..v_columnCount
 37LOOP
 38  CASE v_recTab(j).col_type
 39WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(v_c, j, v_varcharVal);
 40  DBMS_OUTPUT.PUT_LINE(v_recTab(j).col_type || ' ' ||
 41v_recTab(j).col_name || ' ' || v_varcharVal);
 42WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(v_c,j,v_numberVal);
 43  DBMS_OUTPUT.PUT_LINE(v_recTab(j).col_type || ' ' ||
 44v_recTab(j).col_name || ' ' || v_numberVal);
 45WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(v_c,j,v_dateVal);
 46  DBMS_OUTPUT.PUT_LINE(v_recTab(j).col_type || ' ' ||
 47v_recTab(j).col_name || ' ' || v_dateVal);
 48ELSE
 49  DBMS_OUTPUT.PUT_LINE(v_recTab(j).col_type || ' ' ||
 50v_recTab(j).col_name || ' ' || v_varcharVal);
 51  END CASE;
 52END LOOP;
 53 END LOOP;
 54  END;
 55  /

Procedimento criado.

==> Executo primeiro passando um SELECT numa tabela DEPT :

scott@DESENV:SQL>exec PRINT_QUERY_COLUMNS ('select * from dept');
2 DEPTNO 79
1 DNAME Depto 79
1 LOC
2 TESTE
2 DEPTNO 13
1 DNAME teste=  !!
1 LOC
2 TESTE
2 DEPTNO 10
1 DNAME ACCOUNTING
1 LOC NEW YORK
2 TESTE
2 DEPTNO 20
1 DNAME RESEARCH
1 LOC DALLAS
2 TESTE
2 DEPTNO 30
1 DNAME SALES
1 LOC CHICAGO
2 TESTE
2 DEPTNO 40
1 DNAME OPERATIONS
1 LOC BOSTON
2 TESTE

Procedimento PL/SQL concluído com sucesso.

=> Agora chamo a rotina informando uma query onde informo Apenas Algumas 
colunas da tabela EMP :

scott@DESENV:SQL>exec PRINT_QUERY_COLUMNS ('select empno, ename, sal from emp');
2 EMPNO 7369
1 ENAME SMITH
2 SAL 800
2 EMPNO 7499
1 ENAME ALLEN
2 SAL 1600
2 EMPNO 7521
1 ENAME WARD
2 SAL 1250
2 EMPNO 7566
1 ENAME JONES
2 SAL 2975
2 EMPNO 7654
1 ENAME MARTIN
2 SAL 1250
2 EMPNO 7698
1 ENAME BLAKE
2 SAL 2850
2 EMPNO 7782
1 ENAME CLARK
2 SAL 2450
2 EMPNO 7788
1 ENAME SCOTT
2 SAL 3000
2 EMPNO 7839
1 ENAME KING
2 SAL 5000
2 EMPNO 7844
1 ENAME TURNER
2 SAL 1500
2 EMPNO 7876
1 ENAME ADAMS
2 SAL 1100
2 EMPNO 7900
1 ENAME JAMES
2 SAL 950
2 EMPNO 7902
1 ENAME FORD
2 SAL 3000
2 EMPNO 7934
1 ENAME MILLER
2 SAL 1300

Procedimento PL/SQL concluído com sucesso.

==> Posso INCLUSIVE passar cláusulas de WHERE :

scott@DESENV:SQL>exec PRINT_QUERY_COLUMNS ('select empno, ename, sal from emp 
where sal > 3000');
2 EMPNO 7839
1 ENAME KING
2 SAL 5000

Procedimento PL/SQL concluído com sucesso.

scott@DESENV:SQL>

==> OKDOC ??? mais fácil que isso não fica

[]s

  Chiappa





RES: RES: [oracle_br] Re: Tabela Vári avel

2019-02-15 Por tôpico 'Clodoaldo Vilela' clodoaldovil...@yahoo.com.br [oracle_br]
A tabela é criada no momento em que o usuário faz a consulta, com a seguinte 
nomenclatura “TABELA_ANALIT_”, concatenado com o código do usuário que fez a 
consulta, a questão é que eu preciso saber as colunas dessa tabela na 
PROCEDURE, não sei se consegue entender.

 

De: oracle_br@yahoogrupos.com.br [mailto:oracle_br@yahoogrupos.com.br] 
Enviada em: sexta-feira, 15 de fevereiro de 2019 11:46
Para: oracle_br@yahoogrupos.com.br
Assunto: Re: RES: [oracle_br] Re: Tabela Vári avel

 

  

Continuo sem entender completamente (em especial essa expressão "objeto 
tabela", que até onde sei Não Faz Sentido NENHUM no contexto do RDBMS Oracle), 
mas pelo jeito da coisa, TALVEZ o que vc queira é ter um TABLE ** TYPE ** (ie, 
um TYPE baseado numa tabela) e NÃO 'criar uma tabela a partir da variável', mas 
COM o ponto adicional que a tabela a ser referenciada é DINÂMICA, vc não sabe o 
nome dela, sim sim ??
 Se for isso, não há um jeito fácil de se fazer isso, um TYPE (seja ROWTYPE, 
seja TYPE simples) ** tem ** que ser baseado numa tabela ou numa coluna ou num 
cursor PREDEFINIDO e CONHECIDO, ok ?? Uma alternativa poe ser vc criar um 
CURSOR SQL dinâmico e basear teu TYPE nele... E sempre, quando se fala em SQL 
dinâmico, vc tem várias alternativas, a mais flexível/adequada seria o 
DBMS_SQL, veja 
https://stackoverflow..com/questions/26549823/rowtype-variable-from-table-name 
e 
https://asktom.oracle.com/pls/apex/f?p=100:11:0P11_QUESTION_ID:952567346741460
 para alguns exemplos...
 
 ==> Porém, TENHO que frisar : esse negócio de sair criando tabelas on-the-fly 
NÃO É UMA BOA PRÁTICA no RDBMS Oracle : além da DIFICULDADE/COMPLEXIDADE de ter 
que ficar usando SQL dinâmico, como eu disse antes vc FACILMENTE pode ter 
problemas de performance por falta de estatísticas e/ou plano gerado 
inadequadamente - o CORRETO é vc criar a tabela uma só vez antes de começar a 
codificar, já com TODAS as colunas eventualmente necessárias, aí os programas 
SEMPRE usam essa tabela já conhecida...
 
 []s
 
 
   Chiappa





RES: [oracle_br] Re: Tabela Váriavel

2019-02-15 Por tôpico 'Clodoaldo Vilela' clodoaldovil...@yahoo.com.br [oracle_br]
Essa tabela é criada por outro processo “TABELA_ANALIT_” || pCdPessoaUsr, onde 
a tabela analítica fica “TABELA_ANALIT_2”, (2 é o código do usuário), eu quero 
transformar a variável em objeto tabela, ex.: reg_Tabela variável%rowtype;

 

 

 

 

 

 

De: oracle_br@yahoogrupos.com.br [mailto:oracle_br@yahoogrupos.com.br] 
Enviada em: sexta-feira, 15 de fevereiro de 2019 09:21
Para: oracle_br@yahoogrupos.com.br
Assunto: [oracle_br] Re: Tabela Váriavel

 

  

Não entendi *** patavina *** do que vc quis dizer com " criar uma tabela dessa 
variável", até porque uma TABELA vai conter N valores, enquanto uma variável 
vai conter um só, mas o primeiro ponto que TEM que ser compreendido é que no 
RDBMS Oracle, muito embora vc POSSA criar objetos on-the-fly (normalmente com 
SQL dinâmico, via DBMS_SQL ou com EXECUTE IMMEDIATE) o método de trabalho 
PREFERIDO é vc criar TODAS AS TABELAS que vc precisa ANTES dos seus programas 
serem codificados, ok ? Entre outras coisas porque o RDBMS na hora de compilar 
suas procedures/packages/functions/triggers MANTÉM uma relação dos 
objetos/tabelas/etc dos quais dependem, E porque na hora de montar um Plano de 
Execução otimizado para um SQL o RDBMS precisa ter Estatísticas das tabelas 
todas...
 Não esquecendo também, qualquer RDBMS exige que a tabela tenha um nome E que 
os dados estejam 'divididos' em COLUNAS, colunas essas que vc 
(preferencialmente) indica o NOME e o DATATYPE delas : às vezes vc vê uma 
tabela chamada T com uma só coluna C string, aí o programa bota o que quiser do 
jeito que quiser nessa tabela - isso via de regra é um ERRO, já que além de 
perder a Integridade de dados (pois string aceita qquer coisa!!) o RDBMS ** não 
é programado/pensado ** para funcionar assim, nem a linguagem SQL
 A segunda coisa é : estando criada a tabela, para inserir o Oracle aceita 
tanto as tabelas "normais/comuns", cujos dados  ficam PERMANENTES após um 
COMMIT, quanto as tabelas TEMPORÁRIAS, cujos dados só existem enquanto a sessão 
que os criou estiver conectada no banco, quando essa sessão desconecta essa 
tabela é automaticamente limpa...
 E a terceira e última Obs é : seja qual for a tabela que vc criou, vc introduz 
dados nela com INSERT, alterar dados já introduzidos com UPDATE, remove dados 
com DELETE e pesquisa dados já introduzidos anteriormente com SELECT, ok ?? Não 
importa como foi criada, de que tipo é, a linguagem SQL funciona assim
 
 Espero ter dados alguns esclarecimentos, mas se Ainda tem dúvidas, PLEASE 
explica (muito!) melhor o que vc quer fazer e posso tentar dar um exemplo
 
 []s
 
 
   Chiappa





[oracle_br] Tabela Váriavel

2019-02-15 Por tôpico 'Clodoaldo Vilela' clodoaldovil...@yahoo.com.br [oracle_br]
Eu tenho o seguinte código:

Tem como criar uma tabela dessa variável?

 

vcTabelaTemp := Trim(pUserNameConsWeb) || '.EL_CVISITAIMOB_ANALIT_' ||
pCdPessoaUsr;

 

 

CREATE OR REPLACE PROCEDURE SP_CVISITAIMOB ( pCdPessoaUsrIN
USUARIO.CDPESSOAUSR%TYPE

, pUserNameConsWeb  IN
CHAR 

   ) AS

--

-- Variaveis de retorno

-- 

vcMsg   VARCHAR2(32767);

vcTabelaVARCHAR2(500);

vcProc  VARCHAR2(500);

--

-- Variaveis de trabalho

--

vcTabelaBaseVARCHAR2(32767);

BEGIN

--

vcProc:= 'SP_CVISITAIMOB';

vcTabela  := '';

vcMsg := 'Registro não processado com sucesso.';

--

-- Tabela Temporaria - Analitica

--

IF pUserNameConsWeb IS NULL THEN

--

RAISE_APPLICATION_ERROR(-2, 'Name ConsWeb não informado !');

--

END IF;

--

vcTabelaTemp := Trim(pUserNameConsWeb) || '.EL_CVISITAIMOB_ANALIT_' ||
pCdPessoaUsr;

--

EXCEPTION

--

WHEN NO_DATA_FOUND THEN

--

vcMsg := Trim(vcProc) || ':' || Trim(vcTabela) || ' - Dados N?o
Cadastrados.' || ' Comando SQL --> ' || SubStr(vcSQL, 1, 400);

--

-- Retorno

--

RAISE_APPLICATION_ERROR(-2, vcMsg);

--

END;

/