como variar uma tabela no select

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
mcello
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Sex, 31 Out 2008 8:14 am
Localização: são paulo - SP

Pessoal, estou com uma dúvida, eu tenho q fazer a mesma consulta em varias tabelas e eu guardo o nome delas em um varchar2.

Estou usando um cursor no qual eu passo o nome dessa tabela como parâmetro e faço o sele só que o oracle mostra a msg: table or view doesn't exist.

Obs1: considerem que haveria um loop modificando o valor da variavel base

obs2: tentei deixar a declaração no parametro do cursor como varchar2(50) também não deu certo.

exemplo:

Selecionar tudo

 DECLARE

   base VARCHAR2(50);
 

   CURSOR C_PEDIDOS (base VARCHAR2)IS
    select *  FROM base;

  
  BEGIN
       base := 'minha_tabela';
       open C_PEDIDOS(base);
       close C_PEDIDOS;
  END;
joaogarcia
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 91
Registrado em: Ter, 20 Mar 2007 7:19 pm
Localização: Campinas - SP
Contato:
Cordialmente,
João C. Garcia

Dá uma olhada neste tópico. Acho que pode de ajudar:

http://glufke.net/oracle/viewtopic.php?t=333

T+
mcello
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Sex, 31 Out 2008 8:14 am
Localização: são paulo - SP

da forma como é explicado no link sugerido, não serve para mim porque eu só pego os nome da tabelas já dentro da procedure e portanto não poderia passar os nomes como parâmetro.

O que eu preciso é que dentro de um script mais especificamente dentro da minha procedure nesse script, eu consiga variar a tabela que eu estou utilizando no select.
rcoelho_6
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 18
Registrado em: Ter, 04 Nov 2008 1:56 pm
Localização: SP - são Paulo

tente assim:

Selecionar tudo

DECLARE
  v_sql varchar2(2000);
  base VARCHAR2(50);
  c_type is ref_ursor;
  v_cursor c_type;
  v_result minha_tabela%rowtype;
BEGIN
  base := 'minha_tabela';
  v_sql := 'Select * from '|| base;
  open v_cursor for v_sql;
  loop
    fetch v_cursor into v_result;
    ...
  end loop;
  close v_cursor;
END;

Ou talvez desse jeito tambem funcione, precisava testar!

Selecionar tudo

DECLARE
  v_sql varchar2(2000);
  base VARCHAR2(50);
BEGIN
  base := 'minha_tabela';
  v_sql := 'Select * from '|| base;
  for c into v_sql loop
    ...
  end loop;
END;
joaogarcia
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 91
Registrado em: Ter, 20 Mar 2007 7:19 pm
Localização: Campinas - SP
Contato:
Cordialmente,
João C. Garcia

Então, com o execute immediate você teria que montar algo assim:

Selecionar tudo

DECLARE
  --
  /* Para testar, mude o nome da tabela abaixo: */
  V_TABELA  VARCHAR2(30) := 'USER_PROCEDURES';
  V_SCRIPT  VARCHAR2(3000);
  --
  CURSOR C_COLUNAS IS SELECT T.COLUMN_NAME 
                        FROM ALL_TAB_COLS T 
                       WHERE T.TABLE_NAME = V_TABELA;
  --
BEGIN
  --
  V_SCRIPT := 'DECLARE'                                                              ||CHR(10)||
              '  CURSOR C_GERAL IS SELECT * FROM '||V_TABELA||' WHERE ROWNUM <= 1;' ||CHR(10)||
              'BEGIN'                                                                ||CHR(10)||
              '  FOR CUR IN C_GERAL LOOP'                                            ||CHR(10);
  --
  FOR CUR IN C_COLUNAS LOOP  
    --
    V_SCRIPT := V_SCRIPT || '  DBMS_OUTPUT.PUT_LINE(''' ||CUR.COLUMN_NAME|| ': ''||'  ||'CUR.'|| CUR.COLUMN_NAME ||');'||CHR(10);
    --
  END LOOP;
  --
  V_SCRIPT := V_SCRIPT ||'  END LOOP;' ||CHR(10);
  V_SCRIPT := V_SCRIPT ||'  END;';
  --
  EXECUTE IMMEDIATE V_SCRIPT;
  --
END;
T+ aí
mcello
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Sex, 31 Out 2008 8:14 am
Localização: são paulo - SP

O ultimo exemplo (enviado pelo joao garcia) funcionou para a variação da tabela, o que eu ainda não consegui, mas preciso fazer é saber se a query do cursor:

Selecionar tudo

 SELECT * FROM '||V_TABELA||' WHERE ROWNUM <= 1
tem retorno nulo ou não para eu poder usar no meu script, ou seja, preciso do retorno da query como um todo e não de uma coluna específica, só preciso saber se retorna nulo ou não.
joaogarcia
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 91
Registrado em: Ter, 20 Mar 2007 7:19 pm
Localização: Campinas - SP
Contato:
Cordialmente,
João C. Garcia

Não sei se eu entendi, mas vamos lá.
Se a query não retornar nada, simplesmente não vai entrar no for loop...

Esta query que eu enviei, coloquei WHERE ROWNUM <= 1 para restringir os dados (é um exemplo). No seu caso se você quer dar um full na tabela, elimine isso da query.

T+
mcello
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Sex, 31 Out 2008 8:14 am
Localização: são paulo - SP

ao contrario do que o joão disse msmo quando o retorno é nulo é executado a parte do código dentro do for loop, preciso descobrir uma forma de funcionar o retorno nulo, por que ele entra no loop mesmo assim.
joaogarcia
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 91
Registrado em: Ter, 20 Mar 2007 7:19 pm
Localização: Campinas - SP
Contato:
Cordialmente,
João C. Garcia

Posta seu código aí e explica melhor o que precisa fazer...
Fica mais fácil do que ficar analisando o código do exemplo.
mcello
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Sex, 31 Out 2008 8:14 am
Localização: são paulo - SP

Eu faço a query dinamicamente só que eu preciso saber se deu nulo para fazer algumas coisas.

Selecionar tudo

DECLARE 
  -- 
  /* Para testar, mude o nome da tabela abaixo: */ 
  V_TABELA  VARCHAR2(30); 
  V_SCRIPT  VARCHAR2(3000); 
  esse_tem VARCHAR2(30);
  valor VARCHAR2(30);
  teste INTEGER;
  contador integer;
  
  -- 
  CURSOR C_COLUNAS IS SELECT T.COLUMN_NAME 
                        FROM ALL_TAB_COLS T 
                       WHERE T.TABLE_NAME = V_TABELA; 
  -- 
BEGIN 
  -- 
   teste := 0;
  
  contador:=0;
  
   esse_tem:='62015468';
  
   V_TABELA := 'minha_tabela';
  
  V_SCRIPT := 'DECLARE'                                                              ||CHR(10)|| 
              ' CURSOR C_GERAL IS SELECT * FROM '||V_TABELA||' WHERE  atributo = '|| esse_tem ||'and ROWNUM=0;' ||CHR(10)||
              'BEGIN'                                                                ||CHR(10)|| 
              '  FOR CUR IN C_GERAL LOOP'                                            ||CHR(10); 
  -- 
  FOR CUR IN C_COLUNAS  LOOP  
    -- 
    V_SCRIPT := V_SCRIPT || '  DBMS_OUTPUT.PUT_LINE(''' ||CUR.COLUMN_NAME|| ': ''||'  ||'CUR.'|| CUR.COLUMN_NAME ||');'||CHR(10); 
    
    
      dbms_output.put_line('a partir daqui eu faço as coisas');
    
    
    --
    
  END LOOP; 
  -- 
  
  
  
  V_SCRIPT := V_SCRIPT ||'  END LOOP;' ||CHR(10); 
  V_SCRIPT := V_SCRIPT ||'  END;'; 
  -- 
  EXECUTE IMMEDIATE V_SCRIPT;
  
  
  -- 
END;
mcello
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Sex, 31 Out 2008 8:14 am
Localização: são paulo - SP

o contador foi de brinde eu não estou usando agora
mcello
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Sex, 31 Out 2008 8:14 am
Localização: são paulo - SP

utilizei o execute immediate com into aí consegui verificar o retorno do select.

código:

Selecionar tudo

declare 
vRows number;
vTab varchar2(50);
valor VARCHAR2(30);


begin
iccid := '11001100';

vTab :='minha tabela';

execute immediate 'select count(*) from ' || vTab ||' where atributo= '|| valor into vRows;


dbms_output.put_line(vRows);

if(vRows>0)then
dbms_output.put_line('esse não serve!!!!!!!!!!!');
else
dbms_output.put_line('esse serve!!!!!!!!!!!');
end if;

EXCEPTION
        WHEN OTHERS THEN
        dbms_output.put_line('q q houve!!!!!!!!!!!');

end;
Responder
  • Informação
  • Quem está online

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