Por vezes quando estamos a desenvolver uma alteração numa aplicação já existente, há a necessidade de acrescentar, alterar ou até mesmo apagar colunas de uma tabela. Geralmente isso faz-se no arranque da aplicação numa qualquer rotina de actualização. A questão é, como controlamos se essa alteração já foi feita ou não na base de dados?
Há várias formas é certo mas pessoalmente discordo, sou contra, e abomino coisas como:
- Guardar numa tabela da base de dados uma flag boolean que indique se essa actualização já foi feita ou não (e quem controla se a flag já foi criada ou não?);
- Colocar um qualquer controlo para o caso de dar erro ao tentar fazer a actualização, o programa não crachar (e se o erro não for por já ter sido feita a alteração mas sim por um outro motivo qualquer?);
- Fazer update a um campo numa tabela que supostamente irá guardar a “versão da actualização”;
Pense comigo:
Temos tabelas e campos que são objectos numa base de dados. Estes objectos estão referenciados algures, certo? Estão nas tabelas “sysobjects” e “syscolumns”, não é?
Então porque não fazemos assim:
1 2 3 | SELECT * FROM syscolumns LEFT JOIN sysobjects ON syscolumns.id = sysobjects.id WHERE syscolumns.name = 'campo' AND sysobjects.name = 'tabela' |
Se devolver algum registo é porque o campo existe e assim ficamos a saber que se pretendemos apagar este campo o drop não irá dar erro, se não devolver é porque não existe e é seguro criá-lo!
Ou por exemplo, se quisermos só alterar um campo que era smalldatetime e agora queremos que seja datetime:
1 2 3 | SELECT * FROM syscolumns LEFT JOIN sysobjects ON syscolumns.id = sysobjects.id WHERE syscolumns.name = 'campo' AND sysobjects.name = 'tabela' AND syscolumns.xtype = 61 |
Se devolver algum registo é porque o campo já está como datetime e não é preciso fazer mais nada, se não devolver nenhum registo é porque o campo ainda não é datetime e então podemos fazer o nosso alter column!
Ok, eu sei que isto obriga a que seja feita uma instrução para cada alteração enquanto que os outros métodos controlam-nas em “packs” mas um select não é assim tão lento quanto isso e além do mais podemos reduzir tudo (select + add / alter / drop) a uma só instrução:
1 2 3 4 5 | IF NOT EXISTS (SELECT autoval FROM syscolumns LEFT JOIN sysobjects ON syscolumns.id = sysobjects.id WHERE syscolumns.name = 'campo' AND sysobjects.name = 'tabela') ALTER TABLE tabela ADD campo tinyint NOT NULL DEFAULT 1 |
Se conhecer algum método mais simples e mais eficaz do que este, por favor diga-me.
Até lá irei continuar a usá-lo.


Comentários Recentes