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.