기존 SQLite 테이블에 외부 키를 추가하려면 어떻게 해야 합니까?
저는 다음 표를 가지고 있습니다.
CREATE TABLE child(
id INTEGER PRIMARY KEY,
parent_id INTEGER,
description TEXT);
에 외국 키하려면 어떻게 합니까?parent_id
외부 키가 활성화되어 있다고 가정합니다.
대부분의 예제에서는 표를 작성한다고 가정합니다. 기존의 제약 조건에 제약 조건을 추가하려고 합니다.
그럴수는 없어요.
테이블에 외부 키를 추가하는 SQL-92 구문은 다음과 같습니다.
ALTER TABLE child ADD CONSTRAINT fk_child_parent
FOREIGN KEY (parent_id)
REFERENCES parent(id);
SQLite는 다음을 지원하지 않습니다.ADD CONSTRAINT
ALTER TABLE
명령(sqlite.org : SQLite에서 구현하지 않는 SQL 기능).
할 수 sqlite 3.6.1 에서 입니다.CREATE TABLE
다음과 같이
CREATE TABLE child (
id INTEGER PRIMARY KEY,
parent_id INTEGER,
description TEXT,
FOREIGN KEY (parent_id) REFERENCES parent(id)
);
안타깝게도 기존 데이터를 임시 테이블에 저장하고 이전 테이블을 삭제한 다음 FK 제약 조건을 사용하여 새 테이블을 만든 다음 임시 테이블에서 데이터를 다시 복사해야 합니다.(sqlite.org - FAQ: Q11)
표를 변경하고 제약 조건을 사용하는 열을 추가하는 경우 제약 조건을 추가할 수 있습니다.
먼저 parent_id가 없는 테이블을 만듭니다.
CREATE TABLE child(
id INTEGER PRIMARY KEY,
description TEXT);
그런 다음 테이블을 변경합니다.
ALTER TABLE child ADD COLUMN parent_id INTEGER REFERENCES parent(id);
https://www.sqlite.org/lang_altertable.html#otheralter 을 확인해주시기 바랍니다.
SQLite에서 직접 지원하는 스키마 변경 명령은 위에 표시된 "이름 변경 테이블"과 "열 추가" 명령뿐입니다.그러나 응용프로그램은 간단한 연산 순서를 사용하여 테이블 형식을 임의로 변경할 수 있습니다.일부 테이블 X의 스키마 설계를 임의로 변경하는 단계는 다음과 같습니다.
- 외부 키 제약 조건이 활성화된 경우, PRAGMA foreign_keys=를 사용하여 비활성화합니다.쉬는.
- 거래를 시작합니다.
- 테이블 X와 관련된 모든 인덱스 및 트리거의 형식을 기억합니다.이 정보는 아래 8단계에서 필요합니다.한 가지 방법은 SELECT type, sql FROM sqlite_master WHERE tbl_name='X'와 같은 쿼리를 실행하는 것입니다.
- CREATE TABLE을 사용하여 원하는 수정 형식의 테이블 "new_X"를 새로 구성합니다.물론 "new_X"라는 이름이 기존 테이블 이름과 충돌하지 않아야 합니다.
- INSERT INTO new_X SELECT ... FROM X와 같은 문을 사용하여 X에서 new_X로 내용을 전송합니다.
- 기존 테이블 X: Drop TABLE X를 드롭합니다.
- ALTER TABLE new_X RENE TO X를 사용하여 new_X의 이름을 X로 변경합니다.
- CREATE INDEX 및 CREATE TRIGER를 사용하여 테이블 X와 연관된 인덱스와 트리거를 재구성합니다.위의 3단계에서 저장된 트리거 및 인덱스의 이전 형식을 지침으로 사용하여 변경에 적합하도록 변경할 수 있습니다.
- 스키마 변경에 영향을 받는 방식으로 테이블 X를 참조하는 뷰가 있으면 DROP VIEW를 사용하여 해당 뷰를 삭제하고 CREATE VIEW를 사용하여 스키마 변경을 수용하는 데 필요한 모든 변경 사항으로 해당 뷰를 재생성합니다.
- 외부 키 제약 조건이 원래 활성화된 경우 PRAGMA foreign_key_check를 실행하여 스키마 변경이 외부 키 제약 조건을 위반하지 않았는지 확인합니다.
- 2단계에서 시작한 트랜잭션을 커밋합니다.
- 외부 키 제약 조건이 원래 활성화된 경우 지금 다시 활성화합니다.
위의 절차는 완전히 일반적이며 스키마 변경으로 인해 테이블에 저장된 정보가 변경되더라도 작동합니다.따라서 위의 전체 절차는 열을 삭제하거나, 열 순서를 변경하거나, UNIQUE 제약 조건 또는 Primary KEY를 추가 또는 제거하거나, CHECK 또는 FORINE KEY 또는 NOT NULL 제약 조건을 추가하거나, 열에 대한 데이터 유형을 변경하는 데 적합합니다.
예, 열을 새로 추가하지 않아도 가능합니다.데이터베이스가 손상되지 않도록 주의해야 하므로 이 작업을 시도하기 전에 데이터베이스를 완전히 백업해야 합니다.
구체적인 예를 들어:
CREATE TABLE child(
id INTEGER PRIMARY KEY,
parent_id INTEGER,
description TEXT
);
--- create the table we want to reference
create table parent(id integer not null primary key);
--- now we add the foreign key
pragma writable_schema=1;
update SQLITE_MASTER set sql = replace(sql, 'description TEXT)',
'description TEXT, foreign key (parent_id) references parent(id))'
) where name = 'child' and type = 'table';
--- test the foreign key
pragma foreign_keys=on;
insert into parent values(1);
insert into child values(1, 1, 'hi'); --- works
insert into child values(2, 2, 'bye'); --- fails, foreign key violation
또는 일반적으로 다음과 같은 경우:
pragma writable_schema=1;
// replace the entire table's SQL definition, where new_sql_definition contains the foreign key clause you want to add
UPDATE SQLITE_MASTER SET SQL = new_sql_definition where name = 'child' and type = 'table';
// alternatively, you might find it easier to use replace, if you can match the exact end of the sql definition
// for example, if the last column was my_last_column integer not null:
UPDATE SQLITE_MASTER SET SQL = replace(sql, 'my_last_column integer not null', 'my_last_column integer not null, foreign key (col1, col2) references other_table(col1, col2)') where name = 'child' and type = 'table';
pragma writable_schema=0;
어느 쪽이든 변경하기 전에 SQL 정의가 무엇인지 먼저 확인해야 할 것입니다.
select sql from SQLITE_MASTER where name = 'child' and type = 'table';
replace() 접근법을 사용하는 경우 실행하기 전에 다음을 실행하여 replace() 명령을 먼저 테스트하는 것이 도움이 될 수 있습니다.
select replace(sql, ...) from SQLITE_MASTER where name = 'child' and type = 'table';
다음을 시도해 볼 수 있습니다.
ALTER TABLE [Child] ADD COLUMN column_name INTEGER REFERENCES parent_table_name(column_id);
@다니엘 바살로가 말했듯이, 당신은 그것을 할 수 없습니다.사용해야 하는 코드는 다음과 같습니다.
주어진 표:
CREATE TABLE child(
id INTEGER PRIMARY KEY,
parent_id INTEGER,
description TEXT);
다음 Foreignk Key를 추가할 것으로 가정합니다.
FOREIGN KEY (parent_id) REFERENCES parent(id);
그래서 이 테이블을 기반으로 임시 테이블을 작성한 다음 첫 번째 테이블로 새 테이블을 작성하고 마지막으로 임시 테이블의 데이터를 추가합니다.
CREATE TEMPORARY TABLE temp AS
SELECT
id,
parent_id,
description
FROM child;
DROP TABLE child;
CREATE TABLE child (
id INTEGER PRIMARY KEY,
parent_id INTEGER,
description TEXT,
FOREIGN KEY(parent_id) REFERENCES parent(id));
INSERT INTO child
( id,
parent_id,
description)
SELECT
id,
parent_id,
description
FROM temp;
Firefox add-on sqlite-manager를 사용하는 경우 다음을 수행할 수 있습니다.
테이블을 삭제하고 다시 만드는 대신 이렇게 수정하면 됩니다.
Columns(열) 텍스트 상자에서 나열된 마지막 열 이름을 마우스 오른쪽 버튼으로 클릭하여 상황에 맞는 메뉴를 불러오고 Edit Column(열 편집)을 선택합니다.TABLE 정의의 마지막 열이 Primary KEY이면 먼저 새 열을 추가한 다음 새 열의 열 유형을 편집해야 FORNER KEY 정의를 추가할 수 있습니다.열 유형 상자에 쉼표를 추가하고
FOREIGN KEY (parent_id) REFERENCES parent(id)
데이터 형식 뒤의 정의.Change(변경) 버튼을 클릭한 다음 Dangerous Operation(위험 작업) 대화 상자에서 Yes(예) 버튼을 클릭합니다.
참조: Sqlite Manager
sqlite에 대해 Db Browser를 사용하면 테이블을 수정하기가 쉬워집니다.질의를 작성하지 않고 기존 테이블에 외래키를 추가할 수 있습니다.
- DB 브라우저에서 데이터베이스를 엽니다.
- 테이블을 마우스 오른쪽 버튼으로 클릭하고 수정을 클릭하면,
- 거기서 외국 키 열로 스크롤하면,
- 변경할 필드를 두 번 클릭합니다.
- 그런 다음 테이블과 필드를 선택하고 확인을 클릭합니다.
바로 그겁니다.기존 테이블에 외국키를 추가하였습니다.
기존 SQLLite 테이블에 대한 외부 키 생성:
SQL LITE에는 직접적인 방법이 없습니다.아래 쿼리를 실행하여 외부 키로 학생 테이블을 다시 만듭니다.초기 Students 테이블을 생성하고 테이블에 데이터를 삽입한 후 쿼리를 실행합니다.
CREATE TABLE STUDENTS (
STUDENT_ID INT NOT NULL,
FIRST_NAME VARCHAR(50) NOT NULL,
LAST_NAME VARCHAR(50) NOT NULL,
CITY VARCHAR(50) DEFAULT NULL,
BADGE_NO INT DEFAULT NULL
PRIMARY KEY(STUDENT_ID)
);
학생 테이블에 데이터를 삽입합니다.
그러면 외국인 키 추가 : BADGE_NO를 동일한 학생 테이블의 외국인 키로 만들기
BEGIN;
CREATE TABLE STUDENTS_new (
STUDENT_ID INT NOT NULL,
FIRST_NAME VARCHAR(50) NOT NULL,
LAST_NAME VARCHAR(50) NOT NULL,
CITY VARCHAR(50) DEFAULT NULL,
BADGE_NO INT DEFAULT NULL,
PRIMARY KEY(STUDENT_ID) ,
FOREIGN KEY(BADGE_NO) REFERENCES STUDENTS(STUDENT_ID)
);
INSERT INTO STUDENTS_new SELECT * FROM STUDENTS;
DROP TABLE STUDENTS;
ALTER TABLE STUDENTS_new RENAME TO STUDENTS;
COMMIT;
우리는 다른 테이블에서도 외국키를 추가할 수 있습니다.
다른 사람이 SQLiteStudio에 대한 정보가 필요한 경우에는 GUI를 통해 쉽게 사용할 수 있습니다.
열을 두 번 클릭하고 외부 키 행을 두 번 클릭한 다음 외부 키를 선택하고 구성을 클릭합니다.참조 열을 추가한 다음 모든 창에서 확인을 클릭할 수 있습니다.
마지막으로 녹색 체크 표시를 클릭하여 구조의 변경 사항을 커밋합니다.
다음 단계에서는 테이블을 삭제하고 다시 만드는 SQL 스크립트를 생성합니다.!!
데이터베이스에서 데이터를 백업합니다.
@Gaurav Ganani 설명을 시각적으로 완성하기 위해, 저는 잘 작동했습니다(그리고 DB Browser for SQLite를 사용하는 사람들에게도 잘 작동하기를 바랍니다). 여기에 이 이미지를 붙여넣겠습니다.
데이터베이스를 열고 테이블을 마우스 오른쪽 단추로 클릭한 다음 데이터베이스 수정을 선택합니다.열려 있는 창에서 외부 키를 만들고자 하는 열을 선택하고 오른쪽으로 스크롤하면 열로 쓰여진 외부 키를 찾을 수 있고 참조하고 있는 테이블에 열을 더해서 쉽게 선택할 수 있습니다.
기본적으로 당신은 할 수 없지만 그 상황을 우회할 수 있습니다.
기존 테이블에 외부 키 제약 조건을 추가하는 올바른 방법은 다음 명령입니다.
db.execSQL("alter table child add column newCol integer REFERENCES parent(parent_Id)");
그런 다음 Parent_Id 데이터를 newCol에 복사한 다음 Parent_Id 열을 삭제합니다.따라서 임시 테이블이 필요 없습니다.
먼저 하위 테이블에 열 추가Cid
~하듯이int
그리고나서alter table
아래의 코드로이 방법으로 외국 키를 추가할 수 있습니다.Cid
부모 테이블의 기본 키로 사용하고 자식 테이블의 외부 키로 사용합니다...나에게 좋은 일이기 때문에 당신에게 도움이 되기를 바랍니다.
ALTER TABLE [child]
ADD CONSTRAINT [CId]
FOREIGN KEY ([CId])
REFERENCES [Parent]([CId])
ON DELETE CASCADE ON UPDATE NO ACTION;
GO
언급URL : https://stackoverflow.com/questions/1884818/how-do-i-add-a-foreign-key-to-an-existing-sqlite-table
'programing' 카테고리의 다른 글
이름에 panda DataFrame의 특정 문자열이 포함된 열을 삭제합니다. (0) | 2023.10.20 |
---|---|
함수 이름을 문자열로 가져옵니다. (0) | 2023.10.15 |
태그가 필요한 항목에 대한 워드프레스 위젯 업데이트 인스턴스 (0) | 2023.10.15 |
HTML 테이블에서 테두리를 완전히 제거하는 방법 (0) | 2023.10.15 |
HttpClient로 본문 요청 작성 (0) | 2023.10.15 |