Muitas vezes precisamos que uma determinada coluna receba um valor padrão, por exemplo, uma tabela de pedidos que, ao inserir um registro novo, coloca por padrão a data atual no campo que referencia a data do pedido.

Ok, mas como é que eu faço isso?

Muito simples, pequeno gafanhoto, ao criar uma tabela:

CREATE TABLE MinhaTabela 
    (
      Codigo int identity, 
      Nome varchar(100) NOT NULL, 
      Valor int NOT NULL, 
      Data datetime not null CONSTRAINT DF_MinhaTabela_Data default getdate()
    )

Putz! Mas o campo Valor também tinha que ter um valor Default… Será que eu consigo colocar sem ter que refazer a criação ou dropar a coluna?

Claro…

ALTER TABLE MinhaTabela 
  ADD CONSTRAINT DF_MinhaTabela_Valor 
  DEFAULT 0 FOR Valor

Reparem o que aparece ao executar um sp_help:

 

 

Massa né? Tudo bonito!

O Problema é quando, ao invés do código acima, executam isso:

ALTER TABLE MinhaTabelaBugada 
  ADD DEFAULT 0 FOR Valor

Notaram a diferença? Não foi especificado o nome da constraint Default…

Vejam como fica o nome dela quando isso ocorre:

 

 

 

Viram? Digamos que “DF__MinhaTabe__Valor__4A7F2436” não seja um nome bom para uma constraint (e esse nome pode ser muito pior dependendo do tamanho do nome da tabela e da coluna). Sem contar que o sequencial no final é randomico, ou seja, pra mim foi esse valor. Para você, será outro.
Pensando no caso onde o banco vá para n clientes e seja preciso realizar uma alteração no campo que possui essa constraint, a primeira coisa que deve ser feita é dropar essa constraint, alterar a definição da coluna e então recriar a constraint… E aí, como faz?

Toda essa lenga-lenga foi para chegar onde eu queria… 🙂

Fiz um script bem simples para pegar todas as constraints default de um determinado banco que esteja fora da nomenclatura “padrão” (que eu considero boa) DF_Tabela_Coluna para então deixar da forma como precisamos:

DECLARE @Default_Correto varchar(100)
DECLARE @Nome_Objeto varchar(100)
DECLARE @Nome_Coluna varchar(100)
DECLARE @Default_Errado varchar(100)
DECLARE @Default_Definicao varchar(100)
DECLARE @Comando varchar(150)

DECLARE Cur_AjustaDF Cursor 
FOR
select 'DF_' + OBJ.name + '_' + COL.name AS NomeCorreto, OBJ.Name, col.name, DEF.name, DEF.DEFINITION
from sys.columns COL
join sys.default_constraints DEF
ON 
 (COL.object_id = DEF.parent_object_id) AND 
 (COL.column_id = DEF.parent_column_id)
join sys.objects OBJ
ON (COL.object_id = OBJ.object_id)
where
 (DEF.is_system_named = 1) AND
 (OBJ.is_ms_shipped = 0) AND
 (OBJ.type = 'U')

OPEN Cur_AjustaDF

FETCH NEXT FROM Cur_AjustaDF
INTO @Default_Correto, @Nome_Objeto, @Nome_Coluna, @Default_Errado, @Default_Definicao 

WHILE @@FETCH_STATUS = 0
BEGIN
  SET @Comando = ' ALTER TABLE ' + @Nome_Objeto + ' DROP CONSTRAINT ' + @Default_Errado
  EXEC (@Comando)

  SET @Comando = 'ALTER TABLE  '+ @Nome_Objeto + ' ADD CONSTRAINT ' + @Default_Correto + ' DEFAULT ' + @Default_Definicao + ' FOR ' + @Nome_Coluna
  EXEC (@Comando)

FETCH NEXT FROM Cur_AjustaDF
INTO @Default_Correto, @Nome_Objeto, @Nome_Coluna, @Default_Errado, @Default_Definicao 

END
CLOSE Cur_AjustaDF
DEALLOCATE Cur_AjustaDF

Após executar o script acima, a execução do “sp_help MinhaTabela” mostrará a constraint nomeada corretamente…

Caso queiram baixar para ver/brincar/usar, coloquei os scripts aqui

Qualquer comentário a respeito, inclusive melhorias (que muito provavelmente devem existir), façam. 😉

[]’s!