SQL ALTER TABLE

Nenhuma tabela nasce perfeita. A Loja Aurora começou sem o telefone dos clientes, e agora a Ana quer mandar mensagem a eles. Apagar a tabela e criar de novo não dá: os 30 clientes estão lá dentro. Para mudar a estrutura de uma tabela que já tem dados, existe o ALTER TABLE ("altere a tabela"). Nesta aula você vai ver as quatro mudanças que o SQLite faz com ele, as que ele não faz, e o roteiro seguro para essas outras: criar uma tabela nova e mudar os dados de casa.

Você vai aprender
  • Renomear uma tabela (RENAME TO) e uma coluna (RENAME COLUMN).
  • Acrescentar uma coluna (ADD COLUMN), com e sem valor padrão, e as regras que ela não pode ter.
  • Apagar uma coluna (DROP COLUMN), e quando o SQLite se recusa.
  • O que o SQLite não aceita: mudar o tipo de uma coluna, acrescentar um CHECK, mudar várias coisas num comando só.
  • O roteiro para recriar uma tabela sem perder nada, inclusive uma que outras tabelas referenciam.
  • Os erros reais e como o MySQL, o PostgreSQL e o SQL Server fazem.

Os exemplos rodam de verdade no seu navegador, e cada Rodar começa do banco limpo: pode mudar à vontade, nada fica estragado.


A ideia: reformar a casa com a família dentro

Uma tabela com dados é como uma casa com gente morando. Algumas reformas são fáceis e rápidas: trocar a placa com o nome da rua (renomear), pôr uma prateleira nova na parede (acrescentar coluna), tirar um quadro (apagar coluna). Outras são estruturais, como trocar o encanamento todo: aí não tem jeito, a família vai para uma casa nova já pronta, leva a mudança, e a casa velha é demolida. No SQLite, mudar o tipo de uma coluna é uma reforma desse segundo tipo.

Você querNo SQLite
Renomear a tabelaALTER TABLE … RENAME TO …
Renomear uma colunaALTER TABLE … RENAME COLUMN … TO …
Acrescentar uma colunaALTER TABLE … ADD COLUMN …
Apagar uma colunaALTER TABLE … DROP COLUMN …
Mudar o tipo, acrescentar CHECK, UNIQUE, chave…Não tem comando: recriar a tabela (seção 6)

1. Renomear a tabela: RENAME TO

A Ana decidiu que "fornecedores" vai se chamar "parceiros":

ALTER TABLE fornecedores RENAME TO parceiros;

SELECT id, nome, cidade
FROM parceiros
LIMIT 3;
ALTER TABLE fornecedores
"Altere a tabela fornecedores": qual tabela vai mudar.
RENAME TO
"Renomeie para".
parceiros
O nome novo. Os dados não mudam em nada.

E a tabela produtos, que tinha uma chave estrangeira apontando para fornecedores? O SQLite atualizou sozinho:

ALTER TABLE fornecedores RENAME TO parceiros;

SELECT sql FROM sqlite_schema WHERE name = 'produtos';

Repare na linha do fornecedor_id: agora ela diz REFERENCES "parceiros"(id). As aspas duplas foram postas pelo próprio SQLite; aqui elas marcam um nome, não um texto. O nome antigo, porém, deixou de existir: SELECT * FROM fornecedores; agora dá no such table: fornecedores. Todo programa e toda consulta salva que usavam o nome antigo param de funcionar. Renomeie com cuidado.


2. Renomear uma coluna: RENAME COLUMN

A coluna nascimento dos clientes ficaria mais clara como data_nascimento:

ALTER TABLE clientes
RENAME COLUMN nascimento TO data_nascimento;

SELECT nome, data_nascimento
FROM clientes
LIMIT 3;
RENAME COLUMN nascimento
"Renomeie a coluna nascimento". A palavra COLUMN ("coluna") pode ser omitida: RENAME nascimento TO … também funciona, mas com ela fica mais claro.
TO data_nascimento
"Para data_nascimento". Os valores continuam os mesmos, na mesma coluna.

Experimente: o pessoal da loja chama o estado de "UF". Antes do SELECT, renomeie a coluna estado da tabela clientes para uf, e mude o SELECT para mostrar nome e uf dos clientes do Piauí ('PI').

SELECT nome, estado
FROM clientes
WHERE estado = 'PI';
ALTER TABLE clientes RENAME COLUMN estado TO uf;

SELECT nome, uf
FROM clientes
WHERE uf = 'PI';

3. Acrescentar uma coluna: ADD COLUMN

Finalmente, o telefone dos clientes:

ALTER TABLE clientes ADD COLUMN telefone TEXT;

SELECT id, nome, telefone
FROM clientes
LIMIT 3;
ADD COLUMN
"Acrescente a coluna". Como no RENAME, a palavra COLUMN é opcional.
telefone TEXT
A coluna nova, escrita igual a uma linha do CREATE TABLE: nome, tipo e, se quiser, regras.

A coluna nova vai sempre para o fim da tabela, e todas as linhas que já existiam ficam com ela NULL: o banco não tem como adivinhar o telefone de ninguém. No terminal, dá para ver como o SQLite guardou a mudança: ele simplesmente emenda a coluna no fim do CREATE TABLE original.

$ sqlite3 loja.db
SQLite version 3.50.4 2025-07-30 19:33:53
Enter ".help" for usage hints.
sqlite> ALTER TABLE clientes ADD COLUMN telefone TEXT;
sqlite> .schema clientes
CREATE TABLE clientes (
    id         INTEGER PRIMARY KEY,
    nome       TEXT NOT NULL,
    email      TEXT,
    cidade     TEXT,
    estado     TEXT,
    nascimento TEXT,
    vip        INTEGER NOT NULL DEFAULT 0
, telefone TEXT);
sqlite> .quit

Com valor padrão

A Ana vai começar um programa de pontos. Todo cliente começa com 0 pontos, e o campo não pode ficar vazio:

ALTER TABLE clientes
ADD COLUMN pontos INTEGER NOT NULL DEFAULT 0;

SELECT id, nome, pontos
FROM clientes
LIMIT 3;

Com DEFAULT 0 (aula DEFAULT), os 30 clientes que já existiam ganharam 0, e os próximos também ganharão, se ninguém disser outro número. Aqui o DEFAULT é obrigatório: sem ele, o NOT NULL não teria o que pôr nas linhas antigas (veja Quando dá errado).

A coluna nova pode terA coluna nova não pode ter
Qualquer tipoPRIMARY KEY
DEFAULT com um valor fixo (0, 'PI')UNIQUE
NOT NULL, se tiver um DEFAULT que não seja NULLDEFAULT CURRENT_TIMESTAMP (ou outro valor que muda)
REFERENCES, se o DEFAULT for NULLNOT NULL sem DEFAULT

Experimente: acrescente à tabela clientes a coluna pontos, inteira, que nunca fica vazia e começa em 0. Depois mostre id, nome e pontos de todos os clientes.

SELECT id, nome
FROM clientes;
ALTER TABLE clientes
ADD COLUMN pontos INTEGER NOT NULL DEFAULT 0;

SELECT id, nome, pontos
FROM clientes;

4. Apagar uma coluna: DROP COLUMN

A Ana desistiu da marcação de cliente VIP:

ALTER TABLE clientes DROP COLUMN vip;

SELECT * FROM clientes LIMIT 2;
DROP COLUMN vip
"Jogue fora a coluna vip": a coluna some, e os valores dela em todas as linhas também. Não tem desfazer. Se houver alguma chance de precisar dos valores, faça uma cópia antes (aula Criar Tabela a partir de Consulta) ou um backup (aula Backup).

Para apagar duas colunas, são dois comandos, um depois do outro: ALTER TABLE clientes DROP COLUMN email; e ALTER TABLE clientes DROP COLUMN cidade;. O SQLite não aceita uma lista separada por vírgula.

O SQLite se recusa a apagar uma coluna quando outra parte do banco depende dela. Os casos mais comuns:

A coluna…A mensagem
é a chave primáriacannot drop PRIMARY KEY column: "id"
tem UNIQUEcannot drop UNIQUE column: "a"
está num índiceerror in index idx_cidade after drop column: no such column: cidade
aparece no CHECK de outra colunaerror in table t after drop column: no such column: a
está numa FOREIGN KEY (…) escrita no fim da tabelaerror in table t after drop column: unknown column "a" in foreign key definition
não existeno such column: "fone"

As mensagens do tipo error in … after drop column querem dizer "erro em tal lugar depois de apagar a coluna": o SQLite tentou, viu que o índice ou a regra ficaria quebrada, e desfez tudo. Para apagar uma coluna dessas, primeiro apague o que depende dela (o índice, por exemplo, com DROP INDEX) ou recrie a tabela (seção 6).


5. O que o SQLite não faz com ALTER TABLE

Quem vem de outro banco tenta logo mudar o tipo de uma coluna. No SQLite deste guia (a versão 3.50) não existe comando para isso:

ALTER TABLE produtos MODIFY preco NUMERIC;

No terminal, a mensagem vem com a seta apontando onde o SQLite se perdeu:

sqlite> ALTER TABLE produtos MODIFY preco NUMERIC;
Parse error: near "MODIFY": syntax error
  ALTER TABLE produtos MODIFY preco NUMERIC;
                       ^--- error here

A forma do PostgreSQL, ALTER TABLE produtos ALTER COLUMN preco TYPE NUMERIC;, também dá erro de sintaxe, desta vez near "ALTER". Também não dá para acrescentar uma regra a uma tabela pronta (ADD CONSTRAINT, aula CHECK), nem fazer várias mudanças num comando só.

Versões mais novas

A documentação atual do SQLite mostra que versões mais recentes que a deste guia (a partir da 3.53) passaram a aceitar ALTER COLUMN … SET NOT NULL e DROP NOT NULL. Mudar o tipo continua fora da lista. Confira a sua versão com SELECT sqlite_version();; aqui, ela é 3.50.4.


6. Recriar a tabela: a mudança de casa

Para as reformas "estruturais", a documentação do SQLite dá um roteiro de 12 passos. Ele parece grande, mas a ideia é a da família que muda de casa: construir a casa nova, levar a mudança, demolir a velha, pôr a placa com o nome antigo na nova. Vamos começar pelo caso simples.

O caso simples: uma tabela que ninguém referencia

A Ana criou a tabela de cupons com o desconto como TEXT, por engano. Ordenando pelo desconto, a ordem sai errada, porque texto se ordena letra por letra ('10.5' vem antes de '5', como "abacate" vem antes de "banana"):

CREATE TABLE cupons (
    id       INTEGER PRIMARY KEY,
    codigo   TEXT NOT NULL,
    desconto TEXT NOT NULL
);
INSERT INTO cupons (codigo, desconto)
VALUES ('NATAL', '15'), ('BEMVINDO', '10.5'), ('PIAUI', '5');

SELECT codigo, desconto, typeof(desconto)
FROM cupons
ORDER BY desconto;

A mudança de casa, em quatro passos:

CREATE TABLE cupons (
    id       INTEGER PRIMARY KEY,
    codigo   TEXT NOT NULL,
    desconto TEXT NOT NULL
);
INSERT INTO cupons (codigo, desconto)
VALUES ('NATAL', '15'), ('BEMVINDO', '10.5'), ('PIAUI', '5');

-- 1. a casa nova, já do jeito certo
CREATE TABLE cupons_nova (
    id       INTEGER PRIMARY KEY,
    codigo   TEXT NOT NULL,
    desconto REAL NOT NULL
);

-- 2. a mudança: copia tudo, convertendo o desconto
INSERT INTO cupons_nova (id, codigo, desconto)
SELECT id, codigo, CAST(desconto AS REAL)
FROM cupons;

-- 3. demole a velha
DROP TABLE cupons;

-- 4. a placa: a nova ganha o nome antigo
ALTER TABLE cupons_nova RENAME TO cupons;

SELECT codigo, desconto, typeof(desconto)
FROM cupons
ORDER BY desconto;
CREATE TABLE cupons_nova
A tabela nova, com a estrutura que você quer. Aqui você pode mudar tipos, acrescentar CHECK, UNIQUE, tudo.
INSERT INTO … SELECT …
Copia todas as linhas da velha para a nova numa tacada só (aula INSERT INTO SELECT). Copie o id também, para os números não mudarem.
CAST(desconto AS REAL)
"Converta o desconto para REAL": transforma o texto '15' no número 15.0.
DROP TABLE cupons
Apaga a tabela velha (aula DROP TABLE).
RENAME TO cupons
A nova assume o nome antigo, e quem usava cupons continua funcionando.

Agora typeof diz real, e a ordem ficou certa: 5, 10.5, 15.

O roteiro completo: uma tabela que outras referenciam

A tabela produtos é mais delicada: os 220 itens de pedido apontam para ela por chave estrangeira. Se a regra estiver ligada, o DROP TABLE produtos falha (veja a aula FOREIGN KEY). A Ana quer acrescentar duas regras: preço maior que zero e estoque nunca negativo. Este é o roteiro de 12 passos da documentação, simplificado para o que a Loja Aurora tem (ela não tem índices, gatilhos nem views na tabela produtos):

-- passo 1: desliga as chaves estrangeiras (fora da transação!)
PRAGMA foreign_keys = OFF;

-- passo 2: começa uma transação: ou vai tudo, ou nada
BEGIN;

-- passo 4: a tabela nova, com as regras
CREATE TABLE produtos_nova (
    id            INTEGER PRIMARY KEY,
    nome          TEXT NOT NULL,
    categoria_id  INTEGER NOT NULL REFERENCES categorias(id),
    fornecedor_id INTEGER NOT NULL REFERENCES fornecedores(id),
    preco         REAL NOT NULL CHECK (preco > 0),
    estoque       INTEGER NOT NULL DEFAULT 0 CHECK (estoque >= 0),
    descontinuado INTEGER NOT NULL DEFAULT 0
);

-- passo 5: a mudança
INSERT INTO produtos_nova
    (id, nome, categoria_id, fornecedor_id, preco, estoque, descontinuado)
SELECT id, nome, categoria_id, fornecedor_id, preco, estoque, descontinuado
FROM produtos;

-- passo 6: demole a velha
DROP TABLE produtos;

-- passo 7: a placa
ALTER TABLE produtos_nova RENAME TO produtos;

-- passo 10: confere se ninguém ficou órfão (vazio = tudo certo)
PRAGMA foreign_key_check;

-- passo 11: confirma
COMMIT;

-- passo 12: liga as chaves de novo
PRAGMA foreign_keys = ON;

SELECT COUNT(*) AS produtos FROM produtos;
Passo da documentaçãoO que fazNa Loja Aurora
1. PRAGMA foreign_keys = OFFSenão o DROP TABLE esbarra nos itens de pedido.Feito
2. BEGINSe algo der errado no meio, nada muda (aula Transações).Feito
3. Anotar índices, gatilhos e views da tabelaEles somem com o DROP TABLE e precisam ser recriados. Veja com SELECT type, sql FROM sqlite_schema WHERE tbl_name = 'produtos';Não tem nenhum
4. CREATE TABLE da novaA estrutura nova.Feito
5. INSERT INTO … SELECTCopia os dados.Feito: 45 produtos
6. DROP TABLE da velhaApaga a antiga.Feito
7. RENAME TOA nova assume o nome.Feito
8 e 9. Recriar índices, gatilhos e viewsCom o SQL anotado no passo 3.Não tem nenhum
10. PRAGMA foreign_key_checkConfere se alguma linha ficou apontando para o vazio.Feito: vazio
11. COMMITConfirma tudo.Feito
12. PRAGMA foreign_keys = ONVolta a proteger o banco.Feito

Para ver que as regras novas estão valendo, acrescente no fim UPDATE produtos SET preco = -1 WHERE id = 1;: a resposta será CHECK constraint failed: preco > 0.

Por que o PRAGMA fica fora do BEGIN

Dentro de uma transação, o PRAGMA foreign_keys não tem efeito nenhum (e não dá erro). Se você puser o PRAGMA foreign_keys = OFF depois do BEGIN, a regra continua ligada e o DROP TABLE produtos falha. A ordem do roteiro importa.


7. Qual caminho usar

MudançaCaminhoCuidado
Nome da tabelaRENAME TOProgramas que usam o nome antigo param de funcionar.
Nome de uma colunaRENAME COLUMNIdem, para consultas que citam a coluna.
Coluna novaADD COLUMNCom NOT NULL, precisa de DEFAULT. Nada de UNIQUE nem PRIMARY KEY.
Tirar uma colunaDROP COLUMNNão tem desfazer. Recusa se algo depende dela.
Tipo, regras, chave, ordem das colunasRecriar a tabela (seção 6)Use transação; com chaves estrangeiras, o roteiro completo.

Quando dá errado

NOT NULL sem DEFAULT
ALTER TABLE clientes ADD COLUMN pontos INTEGER NOT NULL;

A mensagem: Cannot add a NOT NULL column with default value NULL, "não é possível acrescentar uma coluna NOT NULL com valor padrão NULL". Os 30 clientes antigos ficariam sem valor, e a regra não deixa.

Como consertar: dê um valor padrão: ADD COLUMN pontos INTEGER NOT NULL DEFAULT 0.

UNIQUE ou PRIMARY KEY na coluna nova
ALTER TABLE clientes ADD COLUMN cpf TEXT UNIQUE;

A mensagem: Cannot add a UNIQUE column, "não é possível acrescentar uma coluna UNIQUE". Com PRIMARY KEY, a mensagem é Cannot add a PRIMARY KEY column.

Como consertar: acrescente a coluna sem UNIQUE e crie um índice único depois: CREATE UNIQUE INDEX idx_cpf ON clientes(cpf); (aula Índices). Para chave primária, só recriando a tabela.

DEFAULT com a hora atual
ALTER TABLE clientes
ADD COLUMN criado_em TEXT DEFAULT CURRENT_TIMESTAMP;

A mensagem: Cannot add a column with non-constant default, "não é possível acrescentar uma coluna com padrão não constante". O CURRENT_TIMESTAMP muda a cada segundo, e o SQLite não sabe que hora pôr nas linhas antigas. No CREATE TABLE ele é aceito; no ADD COLUMN, não.

Como consertar: acrescente sem DEFAULT e preencha as linhas antigas com um UPDATE, ou recrie a tabela.

A coluna já existe
ALTER TABLE clientes ADD COLUMN cidade TEXT;

A mensagem: duplicate column name: cidade, "nome de coluna repetido". Acontece muito ao rodar o mesmo roteiro de mudança duas vezes. O mesmo vale para renomear para um nome que já existe: RENAME COLUMN email TO nome dá error in table clientes after rename: duplicate column name: nome.

Usou o nome antigo depois de renomear
ALTER TABLE clientes
RENAME COLUMN nascimento TO data_nascimento;

SELECT nome, nascimento FROM clientes;

A mensagem: no such column: nascimento. O ALTER TABLE funcionou; quem errou foi a consulta, que ainda usa o nome antigo.

Mudar o tipo com MODIFY ou ALTER COLUMN

Já visto na seção 5: near "MODIFY": syntax error ou near "ALTER": syntax error. No SQLite, mudar o tipo é recriar a tabela.


Nos outros bancos

MySQL, PostgreSQL e SQL Server mudam muito mais coisa com ALTER TABLE, inclusive o tipo de uma coluna e as regras, sem recriar a tabela. A escrita muda de um para outro (trechos ilustrativos, não rodam no SQLite):

-- MySQL / MariaDB
ALTER TABLE produtos MODIFY COLUMN preco DECIMAL(10,2) NOT NULL;

-- PostgreSQL
ALTER TABLE produtos ALTER COLUMN preco TYPE numeric(10,2);

-- SQL Server
ALTER TABLE produtos ALTER COLUMN preco DECIMAL(10,2) NOT NULL;

-- nos três: acrescentar uma regra numa tabela pronta
ALTER TABLE produtos ADD CONSTRAINT preco_positivo CHECK (preco > 0);

Renomear também muda: no SQL Server, por exemplo, renomeia-se com o procedimento sp_rename, e não com ALTER TABLE … RENAME. Na dúvida, consulte a documentação do banco que você usa; o grupo "Os Dialetos" do Nível 3 compara os três.


Referência rápida

EscritaO que faz
ALTER TABLE velha RENAME TO nova;Renomeia a tabela (as chaves estrangeiras que apontam para ela são atualizadas).
ALTER TABLE t RENAME COLUMN a TO b;Renomeia uma coluna.
ALTER TABLE t ADD COLUMN c TIPO …;Acrescenta uma coluna no fim; as linhas antigas ficam com o DEFAULT (ou NULL).
ALTER TABLE t DROP COLUMN c;Apaga uma coluna e seus valores.
Recriar: CREATE TABLE t_nova → INSERT INTO t_nova SELECT … FROM t → DROP TABLE t → ALTER TABLE t_nova RENAME TO tQualquer outra mudança. Com chaves estrangeiras: PRAGMA foreign_keys = OFF, BEGIN, …, PRAGMA foreign_key_check, COMMIT, PRAGMA foreign_keys = ON.
MensagemQuer dizer
Cannot add a NOT NULL column with default value NULLColuna nova NOT NULL precisa de DEFAULT.
Cannot add a UNIQUE column / Cannot add a PRIMARY KEY columnEssas regras não entram por ADD COLUMN.
Cannot add a column with non-constant defaultDEFAULT CURRENT_TIMESTAMP não vale no ADD COLUMN.
duplicate column name: cidadeJá existe uma coluna com esse nome.
cannot drop PRIMARY KEY column: "id"A chave primária não pode ser apagada.
error in index … after drop column: …Um índice (ou regra) depende da coluna.
near "MODIFY": syntax errorO SQLite não muda o tipo de coluna: recrie a tabela.

Exercícios

1. Renomear a tabela

Complete para que a tabela categorias passe a se chamar secoes:

ALTER TABLE categorias TO secoes;

2. Coluna nova

Complete para acrescentar a coluna site aos fornecedores:

ALTER TABLE fornecedores COLUMN site TEXT;

3. Depois de ALTER TABLE clientes ADD COLUMN telefone TEXT;, o que os 30 clientes que já existiam têm na coluna telefone?

4. Qual destes comandos o SQLite 3.50 aceita?

5. No roteiro de recriar a tabela produtos, por que o PRAGMA foreign_keys = OFF vem antes do BEGIN?

6. A Ana renomeou fornecedores para parceiros. O que aconteceu com a chave estrangeira produtos.fornecedor_id?

Missão final: o desconto que era texto

Missão: o desconto dos cupons foi criado como TEXT, e a ordem sai errada. Recrie a tabela com o desconto REAL, sem perder os três cupons: crie cupons_nova, copie as linhas convertendo com CAST(desconto AS REAL), apague a velha e dê à nova o nome cupons. O SELECT do fim deve mostrar PIAUI|5.0 em primeiro lugar.

CREATE TABLE cupons (
    id       INTEGER PRIMARY KEY,
    codigo   TEXT NOT NULL,
    desconto TEXT NOT NULL
);
INSERT INTO cupons (codigo, desconto)
VALUES ('NATAL', '15'), ('BEMVINDO', '10.5'), ('PIAUI', '5');

-- escreva aqui a mudança de casa

SELECT codigo, desconto, typeof(desconto)
FROM cupons
ORDER BY desconto;
CREATE TABLE cupons (
    id       INTEGER PRIMARY KEY,
    codigo   TEXT NOT NULL,
    desconto TEXT NOT NULL
);
INSERT INTO cupons (codigo, desconto)
VALUES ('NATAL', '15'), ('BEMVINDO', '10.5'), ('PIAUI', '5');

CREATE TABLE cupons_nova (
    id       INTEGER PRIMARY KEY,
    codigo   TEXT NOT NULL,
    desconto REAL NOT NULL
);
INSERT INTO cupons_nova (id, codigo, desconto)
SELECT id, codigo, CAST(desconto AS REAL)
FROM cupons;
DROP TABLE cupons;
ALTER TABLE cupons_nova RENAME TO cupons;

SELECT codigo, desconto, typeof(desconto)
FROM cupons
ORDER BY desconto;

Resumo

  • ALTER TABLE muda a estrutura de uma tabela que já tem dados, sem apagar as linhas.
  • No SQLite ele faz quatro coisas: RENAME TO (tabela), RENAME COLUMN … TO, ADD COLUMN e DROP COLUMN.
  • A coluna nova vai para o fim e as linhas antigas ganham o DEFAULT ou NULL. NOT NULL exige DEFAULT; UNIQUE, PRIMARY KEY e DEFAULT CURRENT_TIMESTAMP não entram por ADD COLUMN.
  • DROP COLUMN não tem desfazer e é recusado quando a coluna é chave, única, está num índice ou numa regra.
  • Mudar o tipo ou acrescentar regras: recrie a tabela (nova → copiar → apagar a velha → renomear). Com chaves estrangeiras, desligue-as antes do BEGIN, confira com PRAGMA foreign_key_check e ligue de novo depois do COMMIT.
  • MySQL, PostgreSQL e SQL Server mudam tipos e regras direto com ALTER TABLE, cada um com a sua escrita.