SQLite
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> SQLite

Thêm khóa ngoại vào bảng hiện có trong SQLite

SQLite hỗ trợ một tập con rất hạn chế của ALTER TABLE tuyên bố. Những điều duy nhất bạn có thể làm với ALTER TABLE trong SQLite là đổi tên bảng, đổi tên cột trong bảng hoặc thêm cột mới vào bảng hiện có.

Nói cách khác, bạn không thể sử dụng ALTER TABLE để thêm khóa ngoại vào bảng hiện có giống như bạn có thể làm trong các hệ quản trị cơ sở dữ liệu khác.

Do đó, cách duy nhất bạn có thể “thêm” khóa ngoại vào bảng hiện có trong SQLite là tạo một bảng mới với khóa ngoại, sau đó chuyển dữ liệu sang bảng mới.

Có nhiều cách để làm điều này, nhưng có một cách được khuyến nghị.

Cách được Đề xuất

Tài liệu SQLite đề xuất quy trình 12 bước để thực hiện các thay đổi giản đồ đối với bảng.

Đối với mục đích của bài viết này, chúng tôi sẽ chỉ giải quyết việc thêm khóa ngoại.

Để làm cho nó hơi thực tế, chúng tôi sẽ đảm bảo rằng bảng đã chứa dữ liệu.

Bảng gốc không có khóa ngoại

Trước tiên, hãy tạo một bảng không có một khóa ngoại và điền vào nó với dữ liệu.

CREATE TABLE Types( 
    TypeId INTEGER PRIMARY KEY, 
    Type
);

CREATE TABLE Pets( 
    PetId INTEGER PRIMARY KEY, 
    PetName,
    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 );

Trên thực tế, ở đây tôi đã tạo hai bảng và điền dữ liệu vào chúng. Hai bảng, vì một ( Loại ) sẽ có khóa chính và khóa khác ( Thú cưng ) sẽ có khóa ngoại.

Lưu ý rằng tôi không tạo khóa ngoại.

Chúng tôi có thể xác minh rằng không có khóa ngoại nào bằng cách chạy lệnh sau:

PRAGMA foreign_key_list(Pets);

Trong trường hợp của tôi, tôi nhận được kết quả sau:

 

(Ô trống vì không có ràng buộc khóa ngoại nào trên bảng này.)

Bây giờ, hãy “thêm” một khóa ngoại.

Thêm khóa ngoài

Đoạn mã sau thêm khóa ngoại vào bảng của chúng ta bằng cách tạo một bảng mới có ràng buộc khóa ngoại, chuyển dữ liệu sang bảng đó, xóa bảng gốc, sau đó đổi tên bảng mới thành tên của bảng gốc.

PRAGMA foreign_keys = OFF;

BEGIN TRANSACTION;

CREATE TABLE Pets_new( 
    PetId INTEGER PRIMARY KEY, 
    PetName,
    TypeId,
    FOREIGN KEY(TypeId) REFERENCES Types(TypeId)
);

INSERT INTO Pets_new SELECT * FROM Pets;

DROP TABLE Pets;

ALTER TABLE Pets_new RENAME TO Pets;

COMMIT;

PRAGMA foreign_keys = ON;

Đã xong.

Nếu bạn cần tạo lại bất kỳ chỉ mục, trình kích hoạt hoặc chế độ xem nào, hãy thực hiện điều đó sau ALTER TABLE câu lệnh đổi tên bảng (ngay trước COMMIT ).

Bây giờ chúng ta hãy kiểm tra lại bảng xem có các ràng buộc khóa ngoại không.

.mode line
PRAGMA foreign_key_list(Pets);

Kết quả (sử dụng đầu ra dọc):

       id = 0
      seq = 0
    table = Types
     from = TypeId
       to = TypeId
on_update = NO ACTION
on_delete = NO ACTION
    match = NONE

Lần này, chúng ta có thể xem chi tiết về ràng buộc khóa ngoại.

Lưu ý rằng dòng đầu tiên của lệnh của tôi (.mode line ) không liên quan gì đến việc tạo khóa ngoại. Tôi đặt nó ở đó chỉ để thay đổi cách thiết bị đầu cuối của tôi xuất ra kết quả (để bạn không phải cuộn sang bên để xem kết quả).

Một phương pháp thay thế

Khi xem ví dụ trước, bạn có thể nghĩ rằng có một cách hiệu quả hơn để làm điều đó. Ví dụ, bạn có thể làm như thế này:

PRAGMA foreign_keys = OFF;

BEGIN TRANSACTION;

ALTER TABLE Pets RENAME TO Pets_old;

CREATE TABLE Pets( 
    PetId INTEGER PRIMARY KEY, 
    PetName,
    TypeId,
    FOREIGN KEY(TypeId) REFERENCES Types(TypeId)
);

INSERT INTO Pets SELECT * FROM Pets_old;

DROP TABLE Pets_old;

COMMIT;

PRAGMA foreign_keys = ON;

Và đó là sự thật. Với ví dụ của tôi, phương pháp này cũng hoạt động.

Nhưng phương pháp này cũng có khả năng làm hỏng các tham chiếu đến bảng trong bất kỳ trình kích hoạt, chế độ xem và ràng buộc khóa ngoại hiện có nào.

Vì vậy, nếu bảng của bạn đã có các trình kích hoạt, chế độ xem hoặc các ràng buộc khóa ngoại hiện tại, thì có lẽ bạn nên sử dụng phương pháp được đề xuất sẽ an toàn hơn.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Chuyển đổi SQLite sang JSON

  2. ListView từ Sqlite trong android

  3. Gây ra bởi:android.database.sqlite.SQLiteException:không có bảng như vậy:(mã 1) Android

  4. tôi có ứng dụng android lấy dữ liệu từ sqlite và hiển thị dữ liệu trong BaseAdapter .. cách tốt nhất là gì ??

  5. Tôi nên chọn gì - JSON hay SQLite?