sql >> Base de Datos >  >> RDS >> SQLite

Cómo colocar una clave externa en SQLite

Normalmente, si necesita colocar una clave externa en SQL, usaría ALTER TABLE declaración. Pero si está usando SQLite, esa no es una opción.

SQLite admite un subconjunto muy limitado de ALTER TABLE declaración. Lo único que puedes hacer con ALTER TABLE en SQLite es cambiar el nombre de una tabla, cambiar el nombre de una columna dentro de una tabla o agregar una nueva columna a una tabla existente.

En otras palabras, no puedes usar ALTER TABLE para colocar una clave externa como puede hacerlo en otros RDBMS

La forma recomendada de "soltar" una clave externa en SQLite es transferir los datos a una nueva tabla sin una clave externa (o con una diferente, si eso es lo que necesita).

La forma recomendada

La documentación de SQLite recomienda un proceso de 12 pasos para realizar cambios de esquema en una tabla. Usaremos ese proceso para "soltar" una clave externa en el siguiente ejemplo.

Crear una tabla con una clave externa

Primero, creemos una tabla con la clave externa y llenémosla con datos.

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 );

En realidad, aquí creé dos tablas y las llené con datos. Dos tablas, porque la primera (Tipos ) tiene la clave principal y la otra (Mascotas ) tiene la clave foránea. La clave externa se agregó en la última línea de la segunda tabla.

Podemos verificar que la clave externa se creó ejecutando el siguiente 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 los detalles de la restricción de clave externa.

Ahora vamos a "soltar" la clave externa.

"Soltar" la clave foránea

El siguiente código "elimina" la clave externa creando una nueva tabla sin una restricción de clave externa, transfiriendo los datos a esa tabla, eliminando la tabla original y luego renombrando la nueva tabla con el nombre de la tabla 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;

Listo.

Si necesita reconstruir índices, disparadores o vistas, hágalo después de ALTER TABLE declaración que cambia el nombre de la tabla (justo antes de COMMIT ).

Ahora revisemos la tabla en busca de restricciones de clave externa nuevamente.

PRAGMA foreign_key_list(Pets);

Resultado:

 

(Eso está en blanco porque no hay restricciones de clave externa en esta tabla).

Puede usar el mismo método para agregar una clave externa a una tabla existente.

Un método alternativo

Al mirar el ejemplo anterior, podría estar pensando que hay una forma más eficiente de hacerlo. Por ejemplo, podrías hacerlo así:

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;

Y es verdad. Con mi ejemplo, este método funciona igual de bien.

Pero este método también tiene el potencial de corromper las referencias a la tabla en cualquier activador, vista y restricción de clave externa existente.

Entonces, si su tabla ya tiene activadores, vistas o restricciones de clave externa existentes, probablemente sea más seguro usar el método recomendado.