Normalmente, se você precisar descartar uma chave estrangeira no SQL, você usaria o
ALTER TABLE
demonstração. Mas se você estiver usando SQLite, isso não é uma opção. SQLite suporta um subconjunto muito limitado do
ALTER TABLE
demonstração. As únicas coisas que você pode fazer com ALTER TABLE
no SQLite é renomear uma tabela, renomear uma coluna dentro de uma tabela ou adicionar uma nova coluna a uma tabela existente. Em outras palavras, você não pode usar
ALTER TABLE
para descartar uma chave estrangeira como você pode em outros RDBMSs A maneira recomendada de “descartar” uma chave estrangeira no SQLite é, na verdade, transferir os dados para uma nova tabela sem uma chave estrangeira (ou com uma chave diferente, se for o que você precisa).
A maneira recomendada
A documentação do SQLite recomenda um processo de 12 etapas para fazer alterações de esquema em uma tabela. Usaremos esse processo para “descartar” uma chave estrangeira no exemplo a seguir.
Criar uma tabela com uma chave estrangeira
Primeiro, vamos criar uma tabela com a chave estrangeira e preenchê-la com dados.
CREATE TABLE Types(
TypeId INTEGER PRIMARY KEY,
Type
);
CREATE TABLE Pets(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId,
FOREIGN KEY(TypeId) REFERENCES Types(TypeId)
);
INSERT INTO Types VALUES
( NULL, 'Dog' ),
( NULL, 'Cat' ),
( NULL, 'Parakeet' ),
( NULL, 'Hamster' );
INSERT INTO Pets VALUES
( NULL, 'Brush', 3 ),
( NULL, 'Tweet', 3 ),
( NULL, 'Yelp', 1 ),
( NULL, 'Woofer', 1 ),
( NULL, 'Fluff', 2 );
Na verdade, aqui eu criei duas tabelas e as preenchi com dados. Duas tabelas, porque a primeira (Tipos ) tem a chave primária e a outra (Animais de estimação ) tem a chave estrangeira. A chave estrangeira foi adicionada na última linha da segunda tabela.
Podemos verificar se a chave estrangeira foi criada executando o seguinte comando:
PRAGMA foreign_key_list(Pets);
Resultado:
id seq table from to on_update on_delete match -- --- ----- ------ ------ --------- --------- ----- 0 0 Types TypeId TypeId NO ACTION NO ACTION NONE
Podemos ver os detalhes da restrição de chave estrangeira.
Agora vamos “descartar” a chave estrangeira.
"Solte" a chave estrangeira
O código a seguir “elimina” a chave estrangeira criando uma nova tabela sem uma restrição de chave estrangeira, transferindo os dados para essa tabela, descartando a tabela original e renomeando a nova tabela com o nome da tabela original.
PRAGMA foreign_keys = OFF;
BEGIN TRANSACTION;
CREATE TABLE Pets_new(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId
);
INSERT INTO Pets_new SELECT * FROM Pets;
DROP TABLE Pets;
ALTER TABLE Pets_new RENAME TO Pets;
COMMIT;
PRAGMA foreign_keys = ON;
Feito.
Se você precisar reconstruir quaisquer índices, gatilhos ou visualizações, faça isso após o
ALTER TABLE
instrução que renomeia a tabela (logo antes de COMMIT
). Agora vamos verificar a tabela para restrições de chave estrangeira novamente.
PRAGMA foreign_key_list(Pets);
Resultado:
(Isso está em branco porque não há restrições de chave estrangeira nesta tabela.)
Você pode usar o mesmo método para adicionar uma chave estrangeira a uma tabela existente.
Um método alternativo
Ao olhar para o exemplo anterior, você pode estar pensando que existe uma maneira mais eficiente de fazer isso. Por exemplo, você poderia fazer assim:
PRAGMA foreign_keys = OFF;
BEGIN TRANSACTION;
ALTER TABLE Pets RENAME TO Pets_old;
CREATE TABLE Pets(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId
);
INSERT INTO Pets SELECT * FROM Pets_old;
DROP TABLE Pets_old;
COMMIT;
PRAGMA foreign_keys = ON;
E é verdade. Com o meu exemplo, este método funciona tão bem.
Mas esse método também tem o potencial de corromper referências à tabela em quaisquer gatilhos, exibições e restrições de chave estrangeira existentes.
Portanto, se sua tabela já possui gatilhos, visualizações ou restrições de chave estrangeira, provavelmente é mais seguro usar o método recomendado.