• Share
  • ?
  • Profiles ▼
  • Communities ▼
  • Apps ▼

Blogs

  • My Blogs
  • Public Blogs
  • My Updates

This community can have members from outside your organization. iMasters

  • Log in to participate
fd26864d-cb41-49cf-b719-d89c6b072893 Blog

▼ Tags

▼ Similar Entries

Announcing OMEGAMON ...

Blog: System z Mana...
ChrisWalker 270003FTW2
Updated
1 people likes thisLikes 1
No CommentsComments 0

Use command BPMConfi...

Blog: Application I...
YuanShang 27000723E1
Updated
1 people likes thisLikes 1
CommentsComments 1

How To Create Multip...

Blog: Application I...
YuanShang 27000723E1
Updated
1 people likes thisLikes 1
No CommentsComments 0

Come and get it -- I...

Blog: System z Mana...
JoeWinterton 110000BXHR
Updated
2 people like thisLikes 2
CommentsComments 2

Somos todos gerentes...

Blog: Technology Le...
TLCBrazil 270002P9M7
Updated
1 people likes thisLikes 1
No CommentsComments 0

▼ Archive

  • January 2014
  • August 2013
  • July 2013
  • May 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • December 2012
  • November 2012
  • October 2012
  • September 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • April 2010

▼ Blog Authors

iMasters

View All Entries
Clicking the button causes a full page refresh. The user could go to the "Entry list" region to view the new content.) Entry list

Executando declarações UPDATE com chaves primárias compostas

iMasters 27000343BF | | Tags:  banco de dados ‎ | 5,871 Views

Recentemente fui procurado por um colega desenvolvedor para ajudá-lo a resolver um problema que, segundo ele, estava lhe tirando o sono.

O problema parecia muito simples à primeira vista: era necessário escrever uma declaração SQL para atualizar um campo Matched caso um ID de usuário aparecesse em duas tabelas que eram alimentadas com dados de sistemas diferentes.

A coisa parecia elementar, até que meu colega observou um detalhe: as tais tabelas possuíam chaves primárias compostas. Isto é, a chave primária era definida por uma combinação de colunas ao invés de um única coluna, como acontece no caso das chaves primárias simples. E este detalhe faz muita diferença na implementação da solução.

Alguns SGBDs, como o SQL SERVER, suportam o uso de junções de tabelas dentro de declarações UPDATE, o que facilita em alguns casos especiais. Mas a maioria dos SGBDs que eu conheço não aceita esta sintaxe.

Vejamos alguns exemplos de sintaxe.

Digamos que o problema descrito acima envolvesse apenas chaves simples (a coluna UserID). Se eu usasse o SQL SERVER, poderia escrever assim:

--sintaxe SQL SERVER
 UPDATE MyTable
 SET Matched = 1
 FROM MytTable M INNER JOIN OtherTable O ON M.UserID = O.UserID

Uma maneira mais usual de se escrever isso e que seria aceita DB2, ORACLE, POSTGRES e vários outros, seria usando o operador IN na cláusula WHERE.

-- sintaxe genérica (DB2, ORACLE, SQL SERVER, POSTGRES...)
 UPDATE MyTable
 SET Matched = 1
 WHERE UserID IN (SELECT UserID FROM OtherTable)

O problema é que esta solução só funciona quando temos uma única coluna na cláusula WHERE. Ou seja, isso não resolveria o problema de uma tabela com chave primária composta. E como nosso SGBD não suportava uso de JOIN na declaração de UPDATE, tive que encontrar outra estratégia.

Na solução que eu propus para o problema inclui a cláusula WHERE, mas usa outro operador: EXISTS. Este operador é pouco usado e muitas vezes esquecido. Mas cai como uma luva na solução deste problema.

O EXISTS testa se uma subconsulta retorna algum registro. Se retornar 1 ou mais registros, o resultado é VERDADEIRO. Se for vazia, o resultado é FALSO.

No caso em questão, as tabelas envolvidas (MyTable e OtherTable) possuem chaves primárias compostas por dois campos : UserID e Account. A ideia é combinar as chaves das duas tabelas dentro da subconsulta.

Com estas informações, não foi difícil montar uma nova declaração UPDATE, como mostro a seguir:

 UPDATE MyTable M
 SET M.Matched = 1
 WHERE EXISTS (
 SELECT 1
 FROM OtherTable O
 WHERE O.UserID= M.UserID
 AND O.Account = M.Account
 )

Um detalhe: com a consulta acima faz um teste baseado na chave primária das tabelas, é de se esperar que o UPDATE rode com uma boa performance.

Esta solução acabou sendo implementada e a aplicação que a usa vai muito bem, obrigado.

Por hoje é só. Abraço!

***

Artigo de Wagner Crivelini

  • Add a Comment Add a Comment
  • Edit
  • More Actions v
  • Quarantine this Entry
Notify Other People
notification_ex

Send Email Notification

Quarantine this entry

deleteEntry
duplicateEntry

Mark as Duplicate

  • Previous Entry
  • Main
  • Next Entry
Feed for Blog Entries | Feed for Blog Comments | Feed for Comments for this Entry