Tabela sem PK. Como identificar as linhas ?

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
  

Mensagemem Ter, 05 Set 2006 3:30 pm

Seguinte... tenho algumas tabelas onde não existe nenhuma coluna que identifique os registros. O problema é que eu
não posso alterar a tabela para ascrecentar uma coluna, e pretendo pegar alguns registros a cada 10 minutos
para jogar em uma outra tabela, como não tenho nenhuma coluna que identique o registro já selecionado antes gostaria
de saber se alguém tem algum truque que possa me ajudar.

Att,

Ricardo
rnovais
Localização: sao paulo - sp

Mensagemem Ter, 05 Set 2006 11:22 pm

crie uma nova tabela com as mesmas colunas da original + uma coluna de identificador.
Crie uma trigger AFTER INSERT na tabela original, inserindo um registro na nova tabela.

Agora é só trabalhar sempre com a nova tabela, que possui PK... foi a única gambiarra em que pensei...
hitchhiker
Localização: poa

Mensagemem Seg, 25 Set 2006 9:36 am

Todo e qualquer registro no Oracle possui um ROWID (pseudo coluna), que é um número em formato HEXA e unico para cada registro de dados do banco, este registro será somente alterado se o registro for deletado e incluido novamente. Em procedimentos de UPDATE o seu conteudo não é alterado. Em procedimentos de DELETE ele desaparece. Em procedimentos de INSERT ele é criado.
Nota: Esta identificação é gerada pelo banco, você não tem controle sobre a mesma.

Espero ter ajudado.
NiNo
Localização: Sao Paulo

NiNo
Developer

Mensagemem Seg, 25 Set 2006 9:44 am

Pelo que eu sei, não é confiável você fazer referência por ROWID.
Algum DBA poderia explicar se minha afirmação é verdadeira ou falsa? :?
dr_gori
Localização: Portland, OR USA

Thomas F. G

Você já respondeu a dúvida de alguém hoje?
http://glufke.net/oracle/search.php?search_id=unanswered

Mensagemem Qua, 14 Mar 2007 2:54 pm

Dr. Gori,

Acho que é isto o que procurava:


Listagem 2 - Consulta utilizando o ROWID


Esta busca somente acontece se alguma das colunas acessadas não estiver presente no índice. Se todas as colunas acessadas estiverem presentes no índice, então o acesso pelo ROWID não se torna necessário.
Apesar de ser a forma mais rápida de acesso aos dados, não é recomendado que os desenvolvedores utilizem esta forma de acesso diretamente. O ROWID é uma informação interna do Oracle, podendo ser de modificado através de algumas operações de administração do banco de dados, como importação e exportação das tabelas.


Fonte: http://www.linhadecodigo.com.br/artigos.asp?id_ac=768
Trevisolli
Localização: Araraquara - SP

Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Mensagemem Qua, 14 Mar 2007 3:00 pm

Mandou bem!
O ROWID até pode ser usado pra referenciar uma linha quando vai se usar a informação "rapidinho" (logo após buscar o rowid).

Isso porque nesse meio tempo sabemos que não haverá mudança de base, de tablespace, etc... ou seja, não afetará o rowid da linha. Caso se armazene um ROWID pra futuras consultas, talvez algo mudou na base e você estará acessando outra linha.
dr_gori
Localização: Portland, OR USA

Thomas F. G

Você já respondeu a dúvida de alguém hoje?
http://glufke.net/oracle/search.php?search_id=unanswered

Mensagemem Qua, 14 Mar 2007 3:28 pm

Valeu Dr Gori.

Devido à isso, deixou aqui uma opinião para que os demais aqui também opinem:

1) Criar a nova tabela, com uma coluna que irá servir de PK;
2) Exportar os dados para Nova Tabela;
3) Definir a PK;
Trevisolli
Localização: Araraquara - SP

Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Mensagemem Sex, 29 Jun 2007 10:11 am

Bom gente voltando ao assundo de ROWID.

Tenho uma tabela com pk de 5 campos.
Preciso fazer uma trigger para disparar quando da um insert nessa tabela, dai essa trigger insere em um Type de uma package temporariamente o ROWID. e depois (after segmente) eu trabalho com esse ROWID.

Bom o que estou com medo é que na hora de pesquizer por esse ROWID o hexa mudou, será que tem chance de acontecer.

Vou dar um resumo dos codigos

Código: Selecionar todos
CREATE OR REPLACE TRIGGER TG_AFTER_I_GISS_BOLETOS
  AFTER INSERT
  ON GISSONLINE.TB_INTER_BOLETOS_GISS 
  REFERENCING NEW AS NEW OLD AS OLD
  FOR EACH ROW 
BEGIN
  PK_GISSONLINE.adicionaRegistro(:NEW.ROWID,
                                 'TB_INTER_BOLETOS_GISS',
                                 'INSERT'); 
END TG_AFTER_I_GISS_BOLETOS;


Código: Selecionar todos
CREATE OR REPLACE TRIGGER TG_AFTER_I_GISS_BOLETOS
  AFTER INSERT
  ON GISSONLINE.TB_INTER_BOLETOS_GISS 
BEGIN
  PK_GISSONLINE.processaRegistros(); 
END TG_AFTER_I_GISS_BOLETOS;


e na PK_GISSONLINE (uma package) [...] significa que existe mais codigo, mais não importante para a pergunta em questão.
Código: Selecionar todos
CREATE OR REPLACE PACKAGE BODY PK_GISSONLINE IS
[...]
  TYPE tp_change_rec IS RECORD(
     ChaveROWID     ROWID
    ,TableName VARCHAR2(30)
    ,Acao      VARCHAR2(30));

  TYPE tp_change_tab IS TABLE OF tp_change_rec;
  gChangeTab tp_change_tab := tp_change_tab();
  PROCEDURE adicionaRegistro(PChave NUMBER
                            ,PTable VARCHAR2
                            ,PAcao  VARCHAR2) IS
  BEGIN
    IF USER = 'SIATUBLU' THEN
      gChangeTab.EXTEND();
      gChangeTab(gChangeTab.LAST).Chave := PChave;
      gChangeTab(gChangeTab.LAST).TableName := PTable;
      gChangeTab(gChangeTab.LAST).Acao := PAcao;
    END IF;
  END adicionaRegistro;

  PROCEDURE processaRegistros IS
    i NUMBER;
  BEGIN
    IF USER = 'SIATUBLU' THEN
    -- procedure responsável apenas para chamada de outras procedures, conforme situação encrontada
    IF gChangeTab.COUNT > 0 THEN
      FOR i IN gChangeTab.FIRST .. gChangeTab.LAST LOOP
        IF gChangeTab(i).Acao = 'INSERT' THEN
       
          IF gChangeTab(i).TableName = 'TB_INTER_BOLETOS_GISS' THEN
            for rg in (select * from TB_INTER_BOLETOS_GISS' where rowid = gChangeTab(i).ChaveRowID) loop
              -- processamento das informações[...]
            end loop;
          END IF;
        END IF;
     END LOOP;
   END IF;
END processaRegistros ;
[...]
HenriqueMachado
Localização: Blumenau - SC

Abraços,
Henrique Machado Muller

Mensagemem Sex, 29 Jun 2007 10:34 am

Outra coisa pessoal.
Como eu guardo o ROWID em uma variavel que o codigo acima não funcionou.
HenriqueMachado
Localização: Blumenau - SC

Abraços,
Henrique Machado Muller

Mensagemem Sex, 29 Jun 2007 11:25 am

Eu já vi por aí o TO_ROWID, que deixa a uma variável do tipo caracter para o tipo rowid.
As vezes dá umas incompatibilidade de tipos. Tenta usar o TO_ROWID. E se não funcionar, mostra pra gente qual erro está dando.
dr_gori
Localização: Portland, OR USA

Thomas F. G

Você já respondeu a dúvida de alguém hoje?
http://glufke.net/oracle/search.php?search_id=unanswered

Mensagemem Sex, 29 Jun 2007 11:40 am

obrigado dr_gori.

Mais acabei descrobindo qual era o erro no package.
O nome ROWID não poderia ser usado para uma variavel
foi só colocar

ChaveROWID ROWID;

como no exemplo abaixo

Código: Selecionar todos
declare
  TYPE tprec IS RECORD(
     AROWID rowid
    ,TableName VARCHAR2(30));

  TYPE tp_change_tab IS TABLE OF tprec INDEX BY BINARY_INTEGER;
  gChangeTab tp_change_tab;
      i integer;
begin
  i := 1;
for rg in (select rowid , descricao from logradouro where rownum <= 10 ) loop
     gChangeTab(i).AROWID := rg.rowid;
         dbms_output.put_line(i || ':' || rg.rowid ||':' || rg.descricao);
         i := 1 + i;
   end loop;
   dbms_output.put_line(LPAD('-',50,'-'));
   for x in gChangeTab.first .. gChangeTab.last loop
         for rg in (select * from logradouro where rowid = gChangeTab(x).AROWID) loop
           dbms_output.put_line(x || ':' || gChangeTab(x).AROWID ||':' || rg.descricao);
         end loop;
   end loop;
end;
HenriqueMachado
Localização: Blumenau - SC

Abraços,
Henrique Machado Muller

Mensagemem Qui, 20 Nov 2008 8:27 am

Ou fazer assim:


Código: Selecionar todos
DECLARE
   L_rowid rowid;
BEGIN
   INSERT INTO tabela(<colunas>)
   VALUES (<valores>) RETURN ROWID INTO L_rowid;
   
   ...
EXCEPTION
   ...
END;
sandkiller
Localização: Poços de Caldas

Mensagemem Seg, 29 Dez 2008 3:33 pm

É, eu criaria a tabela nova com sua própria PK, mas deve-se tomar cuidado, pois pode ocorrer inconsistência:

Situação 1:

Dados da tabela mãe:

Código: Selecionar todos
nome       idade    telefone
Alfredo       35    1234-5678
Ricardo       35    1234-5678


Dados da nova tabela:

Código: Selecionar todos
cod   nome      idade   telefone
1   Alfredo      35      1234-5678
2   Ricardo      35      1234-5678


Imagine agora que você, na tabela mãe, mude o nome de Ricardo, para Alfredo... como alterar o registro na tabela filha? Você teria que fazer uma verificação antes da alteração, qual é o registro na filha, efetuar a alteração e só então alterar o registro na tabela mãe...

Dá pra fazer, mas vai dar trabalho.
Toad
Localização: Seattle, WA

Matheus H. Gonçalves
www.toad.com.br
www.twitter.com/toadgeek


  • Veja também
    Respostas
    ExibiÇões
    Última mensagem


    Voltar para SQL

    Quem está online

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

cron