UPDATE COM INNER JOIN

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
LoadingXp
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 65
Registrado em: Sex, 30 Mar 2007 11:57 am
Localização: SP
Contato:
Att.

Luciano Alvarenga M. Pires
DBA ORACLE CERTIFICADO
http://fulloracle.blogspot.com
------------------------------------
Dinheiro é o combustivel da sociedade industrial. Mas na sociedade da informática o combustivel, o poder, é o conhecimento.

Pessoal eu venho de SQL Server 2k e lá tem um esquema bem bacana que é o seguinte:

Selecionar tudo


UPDATE TABELA SET
   NOME = TABELA2.NOME
FROM TABELA
   INNER JOIN TABELA2 ON
       TABELA.IDENT = TABELA2.IDENT

Como eu faço isso no Oracle??
Atualmente eu guardo em variaveis e vou atualizando, mas acredito que não é a melhor solução.

Desde já agradesço...
erthal
Rank: Analista Sênior
Rank: Analista Sênior
Mensagens: 130
Registrado em: Seg, 22 Nov 2004 1:45 pm
Localização: Niterói - RJ
Gustavo Erthal Jr. | TRISCAL
...................................................
Rio de Janeiro | (21) 2507-2010
São Paulo | (11) 3167-0526
www.triscal.com.br

Luciano,

O inner join nada mais do que uma igualdade, um join normal.

No oracle você pode usar o inner join, ou a cláusula where que ambos funcionarão. É apenas uma questão de estilo. Eu, por exemplo, prefiro utilizar a cláusula where, porque facilita a minha leitura. Você pode continuar usando o inner join, o outer join, ou o full join.

Abraços,
Gustavo
Hahu
Rank: Analista Sênior
Rank: Analista Sênior
Mensagens: 147
Registrado em: Qui, 16 Mar 2006 11:26 am
Localização: São Paulo
O mundo gira muito!!

Fala erthal,
Boa tarde amigo!
Segue um exp:

Selecionar tudo


UPDATE tab_a INNER JOIN tab_b 
            ON tab_a.col_ID_a = tab_b.col_ID_b 
      SET tab_a.col_c = tab_a.col_c * .95 
 WHERE tab_a.col_d = 'Amigo' 
     AND tab_a.col_d = No;
Qualquer coisas, posta aqui no forum!! :wink:

Abs Hahu
Tutubaraum
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 1
Registrado em: Qua, 11 Fev 2009 10:24 am
Localização: Rio de Janeiro - RJ
cantaMiSSA G/OT#68
"...em terra de cego, quem tem um olho é pirata"

Pessoal... ao invés de fazer com Inner Join, por que não tentam com subselect? é mais rápido, acreditem!

Exemplo

Selecionar tudo

UPDATE 
           (SELECT a11.[coluna_a_atualizar]
            FROM TABELA1 A11, TABELA2 A12, TABELA3 A13
            WHERE A11.[FK] = A12.[FK]
            AND     A12.[FK] = A13.[FK]
            AND     [TODAS AS CONDIÇÕES NECESSÁRIAS]
            ) A
SET A.[coluna_a_atualizar] = [..]
------------------------------
Lembrando que você não precisa colocar nada na cláusula WHERE do UPDATE, porque as suas condições estão todas na "VIEW".

Eu mexo com DW e fiz um update de aproximadamente 948.000 linhas em 1min e meio (98 s)
-------------------------------

Espero que gostem!!!
xereda
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 1
Registrado em: Qui, 14 Out 2010 4:11 pm
Localização: Jonville - SC
Contato:
___________________________
Jackson Ricardo Schroeder
Analista de Sistemas
www.twitter.com/xereda

Este último exemplo está dando o erro ORA-01779 (não é possível modificar uma coluna que mapeie uma tabela não preservada pela chave
). Observe o script abaixo:

Selecionar tudo

update 

(select d.ds_versao 
from documento d, docto_campo_custom d2
where d.nr_documento = 109426
and d.cod_empresa = d2.cod_empresa
and d.nr_documento = d2.nr_documento
and d.nr_versao = d2.nr_versao
) t
set t.ds_versao = t.ds_versao
alguém sabe o motivo.

Desde já agradeco a ajuda,
ZombieW
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 1
Registrado em: Sex, 15 Out 2010 3:55 pm
Localização: São Paulo - SP

Pelo simples motivo de você ter errado na select...

A sua está assim:

Selecionar tudo

update 

(select d.ds_versao 
from documento d, docto_campo_custom d2 
where d.nr_documento = 109426 
and d.cod_empresa = d2.cod_empresa 
and d.nr_documento = d2.nr_documento 
and d.nr_versao = d2.nr_versao 
) t 


set t.ds_versao = t.ds_versao
E o correto é:

Selecionar tudo

update 

(select d.ds_versao 
from d, d2 
where d.nr_documento = 109426 
and d.cod_empresa = d2.cod_empresa 
and d.nr_documento = d2.nr_documento 
and d.nr_versao = d2.nr_versao 
) t 

set t.ds_versao = t.ds_versao
Onde você errou? no FROM, parece que você colocou alguma coisa antes do nome da tabela...
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Caros, não sou muito experiente em PL/SQL, mas ao ver este tópico lembrei de uma situação onde precisei fazer algo parecido e utlizei o exemplo encontrado aqui no fórum. Na dúvida, procurei orientação dos analistas e desenvolvedores mais experientes do que eu, onde os mesmos foram enfaticos e unânimes ao dizer: "nossa que query ninja", rs. Eu permaneci na dúvida em saber se "ninja" seria algo bom ou não, no entanto, me orientaram ao invés de utilizar o JOIN no UPDATE, fazer um cursor com os dados que deveriam ser alterados e em seguida utilizar o UPDATE ou senão, fazer os UPDATES separados, individualmente, quantos fossem necessários.

Por isso, gostaria de saber a opinião dos "senhores". Utilizar o UPDATE com JOIN é uma prática aceitável, viável e recomendada?

Grato.
burga
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Qui, 26 Nov 2009 1:05 pm
Localização: SP

Faz com MERGE:

Selecionar tudo

MERGE INTO 
 TABELA t1
USING
 (SELECT *
  FROM TABELA2
  WHERE ) t2
ON (t1.NOME = t2.NOME)
WHEN MATCHED THEN
  UPDATE SET t1.IDENT = t2.IDENT;
burga
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Qui, 26 Nov 2009 1:05 pm
Localização: SP

Tira o WHERE sobrando da subcolsulta que eu coloquei e esqueci de tirar...
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Senhores desculpe-me reavivar este tópico. Mas novamente voltei a me deparar com esta questão. E apesar das diversas formas de executar este procedimento, seja utilizando joins, subquery, alias, tudo me parece uma grande "gambiarra" que funciona!

Mas a minha questão é: Independente do banco de dados, mas dentro do conceito de banco de dados relacionais, em termos de performance e segurança dos dados esta é uma boa pratica, recomendada, aceitável?

Sendo que poderíamos utilizar cursores, dependendo do caso cursores aninhados.

No aguardo.
Responder
  • Informação
  • Quem está online

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