trazer as colunas de determinada tabela

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
pc_delphi
Rank: Analista Pleno
Rank: Analista Pleno
Mensagens: 128
Registrado em: Qui, 29 Mai 2008 6:44 pm
Localização: São Paulo
Tudo posso, nAquel que me fortalece
Filipenses 4:13

Como faço ou em que entidade eu devo dar um select para me trazer somente os atributos de uma tabela? Quero listar os atributos de uma dada tabela. É na sysobjects ou onde eu vejo isso?
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

User_Tab_Columns - Colunas
User_Tables - Tabelas
User_Tablespaces - Tablespaces
etc
Todas que você tem acesso
ALL_TAB_COLUMNS
ALL_TABLES

Todas se você for DBA
DBA_TAB_COLUMNS
etc
pc_delphi
Rank: Analista Pleno
Rank: Analista Pleno
Mensagens: 128
Registrado em: Qui, 29 Mai 2008 6:44 pm
Localização: São Paulo
Tudo posso, nAquel que me fortalece
Filipenses 4:13

Mais uma pergunta: Eu preciso montar um select que me traga um insert para jogar em outro banco. É possível, montar de tal forma que o insert final já liste todas as colunas sem que eu tenha que escrever uma a uma? Deixa eu explicar melhor. Digamos:

Selecionar tudo

select 'insert into tbl values('||coluna1||','||coluna2||','||coluna3||')'from tbl_mae
tem como evitar de escrever coluna a coluna e as virgulas? Pois há tabelas aqui com 64 campos e preciso trazer tudo. Se houver, como eu faço? Obrigado desde já.
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Esse outro banco é Oracle?

No PLSQL pode exportar , ele monta os inserts, tem heterogenous service pra conectar outros bancos, enfim, se for Oracle para Oracle aconselho usar DBLink, se não for o caso, retorne o post e vamos tentar montar isso aí..
pc_delphi
Rank: Analista Pleno
Rank: Analista Pleno
Mensagens: 128
Registrado em: Qui, 29 Mai 2008 6:44 pm
Localização: São Paulo
Tudo posso, nAquel que me fortalece
Filipenses 4:13

Não, é Firebird. A situação é a seguinte. Tudo que existe no FB nós enviamos para o Oracle(Retaguarda). Acontece que a base FB de umas filiais, foram corrompidas e consequentemente houve perda de dados. Consegui visualizar os dados que foram corrompidos e agora preciso inserir na base FB. São algumas tabelas, ums com 39 campos e outras com 56,12 e 64 campos. Logo montar um select insert na mão é dolorido e improdutivo, já que eu vou deixar pronto para quando acontecer outra vez eu só precisaria mudar a entidade, já fazer na mão teria que alterar sempre os atributos caso houvesse entidade diferente. Esse é meu problema.
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

já tentou fazer o export pelo plsql developer?

tem uma opção gerar sql inserts,

vai ter que fazer um loop na tab_columns, ler a coluna data_type para ver se coloca aspas , se é data, etc, tratar NVL, NULL pra

não vai ser tãoooo simnples...
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

to meio sem tempo agora, de repente te ajuda...

Selecionar tudo

Declare 
  vColunas    VarChar2(32000);
  vInstrucao  VarChar2(32000);
  vTableName  VarChar2(30) := 'ESOBBARRAGEM';

Begin
  For i in (select column_name, table_name
              from user_tab_columns 
             where table_name = vTableName) loop
                
    if (vColunas is null) Then          
      vColunas := i.column_name;
    else 
      vColunas := vColunas || ', '||i.column_name;
    end if; 
            
  End Loop;
  
  vInstrucao := 'INSERT INTO '||vTableName||' ('||vColunas||') VALUES (' ;
  
  dbms_output.put_line(vInstrucao);
  
End;  
 
pc_delphi
Rank: Analista Pleno
Rank: Analista Pleno
Mensagens: 128
Registrado em: Qui, 29 Mai 2008 6:44 pm
Localização: São Paulo
Tudo posso, nAquel que me fortalece
Filipenses 4:13

Então, a dificuldade toda seria trazer o conteúdo dos campos, ou seja, os registros. Essa está sendo a minha dificuldade, de montar um insert com todos eles. Manualmente ok, mas assim, de forma mais "automatizada" é que gerou esse meu post.
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Sim, eu entendi,

a partir do script que eu postei teria que fazer ele pegar os valores da coluna da tabela, após ele montar isso, você pega o resultado e poem no seu

select 'insert aaa' from suatabela

no lugar do 'insert aaa' pega a instrucao gerada pelo script, ou ate poem a palavra select e from e tudo, mas não falta muito não...

mais um loop, tratando se a coluna é NULLABLE, o tipo pra por as Aspas, ai montaria o values, manjou?
pc_delphi
Rank: Analista Pleno
Rank: Analista Pleno
Mensagens: 128
Registrado em: Qui, 29 Mai 2008 6:44 pm
Localização: São Paulo
Tudo posso, nAquel que me fortalece
Filipenses 4:13

Entendi. Eu fiz um cursor e criei uma variável rowtype desse cursor. A idéia seria pegar cada posição dessa variável em um loop e ir concatenando os valores separados por vírgula. Eu não estou conseguindo fazer esse loop, pois não tem como fazer o loop em uma variável de cursor. Veja abaixo como ficou. O dbms_output ficaria dentro desse loop, para ele ir montando o insert linha a linha, ou seja, se tiver 10 registros ele monta 10 insert. É aí que o bicho pega.

Selecionar tudo

Declare 
  vColunas    VarChar2(32000); 
  vInstrucao  VarChar2(32000); 
  vTableName  VarChar2(30) := 'TBL_PEDIDO'; 
  cursor vDados is
    select * from tbl_pedido where substr(n_cod_ped_sistema,5,6)in('040600') and 
                  str_faturante = 77 and d_ent_ped >= '01/01/2010'; 
  vSql vDados%rowtype;
  vValDados   Varchar2(32000);
Begin 
  open  vDados;
  fetch vDados into vSql;
  close vDados;  
  for i in (select column_name, table_name 
              from user_tab_columns 
             where table_name = vTableName) loop                
    if (vColunas is null) Then          
      vColunas := i.column_name; 
    else 
      vColunas := vColunas || ', '||i.column_name; 
    end if;         
  end Loop;  
  vInstrucao := 'INSERT INTO '||vTableName||' ('||vColunas||') VALUES (' || ')';  
  dbms_output.put_line(vInstrucao);   
End;
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Pensei em algo assim:

Selecionar tudo

Declare
  vColunas    VarChar2(32000);
  vValues     VarChar2(32000);
  vInstrucao  VarChar2(32000);
  vTableName  VarChar2(30) := 'ESOBBARRAGEM';

Begin
  For i in (select column_name, table_name, data_type
              from user_tab_columns
             where table_name = vTableName) loop
               
    if (vColunas is null) Then         
      vColunas := i.column_name;
    else
     vColunas := vColunas || ', '||i.column_name;
    end if;
    
    if (vValues is null) Then
      vValues := ''''||'||'||i.column_name;
    else
      vValues := vValues || '||'|| '''' ||',
       '|| ''''||'||'|| i.column_name;
    end if;
           
  End Loop;

  vValues := vValues || '||'|| ''');' || '''';

  vInstrucao := 'SELECT  ''INSERT INTO '||vTableName||' ('||vColunas||') VALUES ('||vValues ||'
                   FROM '||vTableName||' ';
                   
  dbms_output.put_line(substr(vInstrucao,1,255));
  dbms_output.put_line(substr(vInstrucao,256,255));
 
End; 
Agora falta por as aspas nos valores, roda ai, pega o dbms e roda, ele vai gerar o select com insert igual o seu primeiro post, como se você tivesse montado na mao, agora falta por as aspas quando é string e data,
sóóóó isso
pc_delphi
Rank: Analista Pleno
Rank: Analista Pleno
Mensagens: 128
Registrado em: Qui, 29 Mai 2008 6:44 pm
Localização: São Paulo
Tudo posso, nAquel que me fortalece
Filipenses 4:13

Fiz também pelo PL/SQL Developer. Até que não é muito trabalhoso, mas da forma como você me passou é mais elegante, mas consegui. Agora vou tentar pelo seu jeito para aprender e ter um diferencial aqui na empresa. SE não conseguir, eu te falo.
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Cria essa funcao no seu banco de dados,

Selecionar tudo

CREATE OR REPLACE Function Quotes (iTexto in varchar2) return varchar2 is
begin
  return ''''||iTexto||'''';
end;
Depois com esse script a magica é acontece... :D

Selecionar tudo

Declare
  vColunas    VarChar2(32000);
  vValues     VarChar2(32000);
  vInstrucao  VarChar2(32000);
  vTableName  VarChar2(30) := 'ESOBBARRAGEM';
  
Begin
  For i in (select column_name, table_name, data_type
              from user_tab_columns
             where table_name = vTableName) loop
               
    if (vColunas is null) Then         
      vColunas := i.column_name;
    else
     vColunas := vColunas ||', '|| i.column_name;
    end if;
    
    if (vValues is null) Then
      vValues := ''''||'||'||'quotes('||i.column_name||')';
    else
      vValues := vValues || '||'|| '''' ||',
       '|| ''''||'||'|| 'quotes('||i.column_name||')';
    end if;
           
  End Loop;

  vValues := vValues || '||'|| ''');' || '''';

  vInstrucao := 'SELECT  ''INSERT INTO '||vTableName||' ('||vColunas||') VALUES ('||vValues ||'
                   FROM '||vTableName||' ';
                   
  dbms_output.put_line(substr(vInstrucao,1,255));
  dbms_output.put_line(substr(vInstrucao,256,255));

End; 
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Depois, você faz,

Selecionar tudo

SPOOL C:\tabelaX.sql
roda o select que o script gera,

Selecionar tudo

spool off;
está lá a saida pronta pra rodar no outro banco...

abraço
pc_delphi
Rank: Analista Pleno
Rank: Analista Pleno
Mensagens: 128
Registrado em: Qui, 29 Mai 2008 6:44 pm
Localização: São Paulo
Tudo posso, nAquel que me fortalece
Filipenses 4:13

Diego, te agradeço pacas pela sua paciência. Não deu certo aqui comigo, devido eu não poder criar a função quotes, devido ser um banco de produção. Estou fazendo na mão mesmo, só para entregar o serviço e depois com mais calma ou em casa, vou testar isso que você me mandou e aí sim, poderei dar uma resposta se funcionou ou não. Obrigado mesmo pelo tempo dispensado a tentar me ajudar. Valeu!
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Tranquilo cara, precisando to por aqui, a função somente coloca duas aspas em cada lado do que lhe é passado como parametro,

para facilitar, pois vira uma confusão esse tanto de ASPAS , rsrs

abraço
Responder
  • Informação
  • Quem está online

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