Página 1 de 1

Tabela sem PK. Como identificar as linhas ?

Enviado: Ter, 05 Set 2006 3:30 pm
por rnovais
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

Enviado: Ter, 05 Set 2006 11:22 pm
por hitchhiker
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...

Enviado: Seg, 25 Set 2006 9:36 am
por NiNo
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.

Enviado: Seg, 25 Set 2006 9:44 am
por dr_gori
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? :?

Enviado: Qua, 14 Mar 2007 2:54 pm
por Trevisolli
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

Enviado: Qua, 14 Mar 2007 3:00 pm
por dr_gori
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.

Enviado: Qua, 14 Mar 2007 3:28 pm
por Trevisolli
Valeu Dr Gori.

Devido à isso, deixou aqui uma opinião para que os demais aqui tb 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;

Enviado: Sex, 29 Jun 2007 10:11 am
por HenriqueMachado
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

Selecionar tudo

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;

Selecionar tudo

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.

Selecionar tudo

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 ; 
[...]

Enviado: Sex, 29 Jun 2007 10:34 am
por HenriqueMachado
Outra coisa pessoal.
Como eu guardo o ROWID em uma variavel que o codigo acima não funcionou.

Enviado: Sex, 29 Jun 2007 11:25 am
por dr_gori
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.

Enviado: Sex, 29 Jun 2007 11:40 am
por HenriqueMachado
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

Selecionar tudo

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;

Enviado: Qui, 20 Nov 2008 8:27 am
por sandkiller
Ou fazer assim:

Selecionar tudo

DECLARE
   L_rowid rowid;
BEGIN
   INSERT INTO tabela(<colunas>)
   VALUES (<valores>) RETURN ROWID INTO L_rowid;
   
   ...
EXCEPTION
   ...
END;

Enviado: Seg, 29 Dez 2008 3:33 pm
por Toad
É, 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:

Selecionar tudo

nome       idade    telefone
Alfredo       35    1234-5678
Ricardo       35    1234-5678
Dados da nova tabela:

Selecionar tudo

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.