Quem mexeu na minha PK?

Mexer numa Chave Primária é sempre algo trabalhoso. Se o sistema for grande e que já estiver em produção então… é no mínimo delicado. Há uma série de pequenos passos propensos a erros que podem acontecer no caminho.

Tive estes dias de alterar o conteúdo de uma PK vou mostrar aqui o que eu fiz para evitar alguns erros comuns e agilizar a operação.

A idéia aqui é utilizar um pouco de SQL para gerar a maior parte dos comandos DDL para nós sem ter que digitar linha por linha, consultando quase sempre o nosso dicionário de dados.

Neste exemplo, foi alterado o conteúdo de uma PK, como por exemplo trocar o número do RG pelo CPF. A estrutura das operações é algo assim:

  1. Tirar backup de tudo antes de mais nada!
  2. Criar uma tabela ‘temp’ para conter os dados relativos às tabelas e campos que serão afetados;
  3. Carretar a tabela com os dados;
  4. Remover todas as chaves estrangeiras das tabelas citadas em ‘temp’;
  5. Remover todas as chaves primárias das tabelas citatas em ‘temp’;
  6. Tirar um backup dos dados da coluna atual renomeando colunas que serão alteradas com o sufixo ‘_old’;
  7. Checar e remover as restrições de ‘NOT NULL’ nas colunas renomeadas;
  8. Criar novas colunas para receber os dados;
  9. Rodar scripts para atualizar os dados nos novos campos;
  10. Recriar as chaves primárias removidas;
  11. Recriar as chaves estrangeiras removidas;
  12. Testar

Ao invés de rodar cada etapa isoladamente a minha idéia é primeiro rodar os scripts abaixo seqüencialmente, guardar o resultado de cada um e só depois de gravar em disco todos o resultado guardado é que você começa a executá-los. O motivo disto é bastante simples: os scripts irão remover uma série de constraints criando comandos do tipo ALTER TABLE DROP. Se você rodar estes comandos antes de gerar os comandos que irão recria-los no final do processo, você não conseguirá descobrir como eram os constraints, portanto não poderá recriar os comandos ALTER TABLE ADD. Se fizer isso, você terá que recorrer a sua documentação e criar os comandos na mão.

Não deixe de fazer um backup disto e nunca execute isto pela primeira vez direto na base de produção. Utilize uma base de teste primeiro.

Bom… vamos colocar a mão na massa agora e ver como podemos agilizar algumas coizas:

  • Criar a tabela ‘temp’
  • Popular a tabela

Coloque na forma de inserts (um bom editor e um pouco de regex vão lhe ajudar) o nome das tabelas e colunas que sofrerão alteração.

Fazer isso parece dar mais trabalho, mas na verdade reaproveitaremos estes valores algumas vezes, acaba sendo bastante prático.

  • Remover os constraints FK
  • Remover os constraints PK:
  • Renomear os campos:
  • Alterar para NULL os campos renomeados
  • Recriar os campos para receberem os novos valores:
Aqui houve uma aplicação da “lei no mínimo esforço” no sentido em que me preocupei apenas com os tipos de dados que eu já sabia que seriam afetatos, portanto não me preocupei com outras possibilidades. Isto poderia ser facilmente ser resolvido ampliando este SQL.

  • Recriar as PKs:
  • Recriar FKs
OBS:Não esqueça de verificar se o número de Constraints removidas é igual ao número de constraints criadas.

Os scripts para criar as constraints deram um pouco mais de trabalho e podem quebrar um bom galho em outras situações com poucas adaptações, como quando você precisa adicionar ou remover um campo numa PK composta.

Estes Scripts foram testados no Oracle 9i. Sei que seria simples fazer algo semelhante para o PostgreSQL ou qualquer outro SGDB com acesso ao ‘Information Schema’ (o Oracle não usa este nome pois não segue o padrão SQL neste ponto) e alguma linguagem PL.

1 comentário

  1. anônimo Responder

    Deuses trabalham com Oracle
    Semi-Deuses trabalham com PostgreSQL
    Humanos trabalham com MySQL

    hum…

    acho sou humano. (fike)

  2. Pingback: SAVEPOINT » Não use DELETE, use INSERT!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *