DDL
데이터 정의 언어로 객페(OBJECT)를 만들고(CREATE), 수정하고(ALTER), 삭제(DROP)하는 구문을 말함
오라클 객체 종류
테이블(TABLE), 뷰(VIEW), 시퀀스(SEQUENCE), 인덱스(INDEX), 패키지(PACKAGE),
프로시저(PROCEDUAL), 함수(FUNCTION), 트리거(TRIGGER), 동의어(SYNONYM), 사용자(USER)
CREATE
테이블이나 인덱스, 뷰 등 데이터 베이스 객체를 생성하는 구문
테이블로 생성된 객체는 DROP 구문을 통해 제거할 수 있음
테이블이란?
행(row)과 열(cloumm)으로 구성되는 가장 기본적인 데이터베이스 객체
데이터베이스 내에서 모든 데이터는 테이블을 통해서 저장된다.
--[표현식]
/*
CREATE TABLE 테이블명 (
컬럼명 자료형(크기),
컬럼명 자료형(크기),
컬럼명 자료형(크기),
....
);
/*
자료형
NUMBER : 숫자형(정수,실수)
CHAR(크기) : 고정길이 문자형(최대 2000BYTE)
--> ex) CHAR(10) 컬럼에 'ABC' 3BYTE 문자열만 저장해도 10BYTE 저장공간을 모두 사용.
VARCHAR2(크기) : 가변길이 문자형 (4000BYTE)
--> ex) VARCHAR2(10) 컬럼에 'ABC' 3BYTE 문자열만 저장하면 나머지 7BYTE 반환함
DATE : 날짜 타입
BLOB : 대용량 이진 데이터(4GB)
CLOB : 대용량 문자 데이터(4GB)
CHARACTER
CHAR
CHAR(SIZE[(byte| char)]
SIZE : 포함된 문자(열)의 크기
지정한 크기보다 작은 문자(열)가 입력되면 남는 공간은 공백으로 채움
*데이터는 "를 사용하여 표기하고 대.소문자를 구분함

VARCHAR2
VARCHAR2( SIZE [(byte | char)]
SIZE : 포함된 문자(열)크기
크기가 0인 값은 NULL로 인식
*데이터는 "를 사용하여 표기하고 대.소문자를 구분함

NUMBER
NUMBER[( P [, S])]
P : 표현할 수 있는 전체 숫자 자리 수(1~38)
S : 소수점 이하 자리 수 (-84 ~127

NUMBER 타입사용시 주의사항
NUMBER 타입 컬럼에 데이터 삽입 시
제일 앞에 0이 있으면 이를 자동으로 제거함
전화번호, 주민번호처럼 숫자로만 되어있는 데이터라도
0으로 시작할 가능성이 있으면 CHAR,VARCHAR2같은 문자형 사용
DATE
*일자(세기/년/월/일) 및 시간(시/분/초) 정보 관리
기본적으로 화면에 년/월/일 정보만 표기
날짜 연산 및 비교 가능

컬럼 주석
테이블의 컬럼에 주석을 다는 구문
예시
-- 2. 컬럼에 주석 달기
-- [표현식]
-- COMMENT ON COLUMN 테이블명.컬럼명 IS '주석내용';
COMMENT ON COLUMN MEMBER.MEMBER_ID IS '회원아이디';
COMMENT ON COLUMN MEMBER.MEMBER_PWD IS '회원 비밀번호';
COMMENT ON COLUMN MEMBER.MEMBER_NAME IS '회원 이름';
COMMENT ON COLUMN MEMBER.MEMBER_SSN IS '회원 주민 등록 번호';
COMMENT ON COLUMN MEMBER.ENROLL_DATE IS '회원 가입일';
제약조건(CONSTRAINTS)
사용자가 원하는 조건의 데이터만 유지하기 위해서 특정 컬럼에 설정하는 제약.
데이터 무결성 보장을 목적으로 함. --> 중복 데이터 X
제약조건 종류
PRIMARY KEY, NOT NULL, UNIQUE, CHECK, FOREIGN KEY
NOT NULL
해당 컬럼에 반드시 값이 기록되어야 하는 경우 사용
삽입/수정 시 NULL값을 허용하지 않도록 컬럼레벨에서 제한
예시
CREATE TABLE USER_USER_NN(
USER_NO NUMBER NOT NULL, -- 사용자번호 (모든 사용자는 사용자 번호가 있어야한다.)
--> 컬럼레벨 제약조건 설정
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50)
);
INSERT INTO USER_USER_NN
VALUES(1,'USER01','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr');
INSERT INTO USER_USER_NN
VALUES(NULL,NULL,NULL,NULL,NULL,'010-1234-5678','hong1234@kh.or,kr');
--> NOT NULL 제약조건 위배되어 오류 발생
-- ORA-01400: NULL을 ("KH"."USER_USER_NN"."USER_NO") 안에 삽입할 수 없습니다
UNIQUE 제약 조건
컬럼의 입력값에 대해서 중복을 제한하는 제약조건
컬럼레벨에서 설정 가능, 테이블 레벨에서 설정 가능
단, UNIQUE 제약조건이 설정된 컬럼에 NULL 값은 중복 삽입 가능.
테이블 레벨 : 테이블 생성 시 컬럼 정의가 끝난 후 마지막에 작성
예시
-- UNIQUE 제약조건 테이블 생성
CREATE TABLE USER_USED_UK(
USER_NO NUMBER,
--USER_ID VARCHAR2(20) UNIQUE, -- 컬럼레벨 (제약조건명 미지정)
--USER_ID VARCHAR(20) CONSTRAINT USER_ID_U UNIQUE -- 컬럼레벨 (제약조건명 지정)
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50),
/테이블 레벨/
--UNIQUE(USER_ID) -- 테이블레벨 (제약조건명 미지정
CONSTRAINT USER_ID_U UNIQUE(USER_ID) -- 테이블 레벨 (제약조건명 지정)
);
INSERT INTO USER_USED_UK
VALUES (1,'USER01','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr');
INSERT INTO USER_USED_UK
VALUES (1,'USER01','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr');
--ORA-00001: 무결성 제약 조건(KH.USER_ID_U)에 위배됩니다
INSERT INTO USER_USED_UK
VALUES (1,NULL,'PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr');
INSERT INTO USER_USED_UK
VALUES (1,NULL,'PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr');
--> 아이디에 NULL 값 중복 삽입 가능
UNIQUE 복합키
두 개 이상의 컬럼을 묶어서 하나의 UNIQUE 제약조건을 설정함
복합키 지정은 테이블 레벨만 가능하다!
복합키는 지정되는 모든 컬럼의 값이 같을때 위배된다!*
예시
CREATE TABLE USER_USED_UK2(
USER_NO NUMBER,
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50),
CONSTRAINT USER_ID_NAME_U UNIQUE(USER_ID, USER_NAME) );
INSERT INTO USER_USED_UK2
VALUES (1,'USER01','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr');
INSERT INTO USER_USED_UK2
VALUES (1,'USER02','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr');
INSERT INTO USER_USED_UK2
VALUES (1,'USER01','PASS01','고길동','남','010-1234-5678','hong1234@kh.or,kr');
INSERT INTO USER_USED_UK2
VALUES (1,'USER01','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr');
-- ORA-00001: 무결성 제약 조건(KH.USER_ID_NAME_U)에 위배됩니다
PRIMARY KEY(기본키) 제약조건
테이블에서 한 행의 정보를 찾기위해 사용할 컬럼을 의미함
테이블에 대한 식별자(학번,사번,회원번호) 역할을 함
NOT NULL + UNIQUE 제약조건의 의미 --> 중복되지 않는 값이 필수로 존재해야 함
한 테이블 당 한개만 설정할 수 있음
컬럼레벨, 테이블레벨 둘다 설정 가능함
한개 컬럼에 설정할 수 도있고, 여러개의 컬럼을 묶어서 설정할 수 있음
예시
CREATE TABLE USER_USED_PK(
USER_NO NUMBER CONSTRAINT USER_NO_PK PRIMARY KEY, -- 컬럼레벨
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50) );
-- 테이블레벨
--CONSTRAINT USER_NO_PK PRIMARY KEY(USER_ID)
INSERT INTO USER_USED_PK
VALUES (1,'USER01','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr');
INSERT INTO USER_USED_PK
VALUES (1,'USER02','PASS01','이순신','남','010-5678-9012','hong1234@kh.or,kr');
-- ORA-00001: 무결성 제약 조건(KH.USER_NO_PK)에 위배됩니다
--> 기본키 중복으로 오류
INSERT INTO USER_USED_PK
VALUES (NULL,'USER02','PASS01','이순신','남','010-5678-9012','hong1234@kh.or,kr');
-- : ORA-01400: NULL을 ("KH"."USER_USED_PK"."USER_NO") 안에 삽입할 수 없습니다
-- 기봌키가 NULL 이므로 오류
PRIMARY 복합키 (테이블 레벨만 가능)
CREATE TABLE USER_USED_PK2(
USER_NO NUMBER,
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50),
CONSTRAINT USER_NO_ID_PK PRIMARY KEY(USER_ID, USER_NO) -- 복합키
);
INSERT INTO USER_USED_PK2
VALUES (1,'USER01','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr');
INSERT INTO USER_USED_PK2
VALUES (1,'USER02','PASS01','이순신','남','010-1234-5678','hong1234@kh.or,kr');
INSERT INTO USER_USED_PK2
VALUES (2,'USER01','PASS01','유관순','남','010-1234-5678','hong1234@kh.or,kr');
INSERT INTO USER_USED_PK
VALUES (1,'USER01','PASS01','유관순','남','010-1234-5678','hong1234@kh.or,kr');
-- ORA-00001: 무결성 제약 조건(KH.USER_NO_PK)에 위배됩니다
-- 회원 번호와 아이디 둘다 중복 되었을 때만 제약조건 위배 에러 발생
INSERT INTO USER_USED_PK2
VALUES (NULL,NULL,'PASS01','유관순','남','010-1234-5678','hong1234@kh.or,kr');
-- PRIMARY KEY는 NULL이 들어갈 수 없다
-- ORA-01400: NULL을 ("KH"."USER_USED_PK2"."USER_NO") 안에 삽입할 수 없습니다
FOREIGN KEY(외부키/외래키) 제약조건
창조된 다른 테이블의 컬럼이 제공하는 값만 사용할 수 있음
FOREIGN KEY 제약조건에 의해서 테이블간 관계가 형성됨
제공하는 값 외에는 NULL(참조하는 값 없음) 을 사용할 수 있음
컬럼레벨일 경우
컬럼명 자료형 (크기) [CONSTRAINT 이름] REFERENCES 참조할 테이블명[(참조할 컬럼)][삭제룰]
테이블일 경우[CONSTRAINT 이름] FOREIGN KEY (적용할 컬럼명) REFERENCES 참조할 테이블명[(참조할컬럼)][삭제룰]
참조 될 수 있는 컬럼은 PRIMARY KEY 컬럼과, UNIQUE 지정된 컬럼만 외래키로 사용할 수 있음
참조형 테이블의 참조할 컬럼명이 생략되면,PRIMARY KEY 로 설정된 컬럼이 자동 참조할 컬럼이 됨
CREATE TABLE USER_GRADE2(
GRADE_CODE NUMBER PRIMARY KEY,
GRADE_NAME VARCHAR2(30) NOT NULL
);
INSERT INTO USER_GRADE2 VALUES (10,'일반회원');
INSERT INTO USER_GRADE2 VALUES (20,'우수회원');
INSERT INTO USER_GRADE2 VALUES (30,'특별회원');
SELECT * FROM USER_GRADE;
CREATE TABLE USER_USED_FK2(
USER_NO NUMBER PRIMARY KEY,
USER_ID VARCHAR2(20) UNIQUE,
USER_PWD VARCHAR2(30) NOT NULL,
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50),
GRADE_CODE NUMBER CONSTRAINT GRADE_CODE_FK2 REFERENCES USER_GRADE2 ON DELETE SET NULL
/삭제옵션/
) ;
COMMIT;
INSERT INTO USER_USED_FK2
VALUES (1,'USER01','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr', 10);
INSERT INTO USER_USED_FK2
VALUES (2,'USER02','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr', 10);
INSERT INTO USER_USED_FK2
VALUES (3,'USER03','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr', 30);
INSERT INTO USER_USED_FK2
VALUES (4,'USER04','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr', NULL);
INSERT INTO USER_USED_FK
VALUES (5,'USER05','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr', 50);
-- ORA-02291: 무결성 제약조건(KH.GRADE_CODE_FK)이 위배되었습니다- 부모 키가 없습니다
--> 50 이라는 값은 USER_GRADE 테이블 GRADE_CODE 컬럼에서 제공하는 값이 아니므로
-- 외래키 제약조건에 위배되어 오류 발생.
COMMIT;
SELECT FROM USER_GRADE2;
SELECT FROM USER_USED_FK2;
DELETE FROM USER_GRADE2
WHERE GRADE_CODE = 10;
SELECT * FROM USER_USED_FK2;
ON DELETE CASCADE : 부모키 삭제 시 자식키도 함께 삭제됨
부모키 삭제 시 값을 사용하는 자식 테이블의 컬럼에 해당하는 행이 삭제가 됨
참조항 테이블의 참조할 컬럼명이 생략되면,PRIMARY KEY로 설정된 컬럼이 자동 참조할 컬럼이 됨
CREATE TABLE USER_GRADE3(
GRADE_CODE NUMBER PRIMARY KEY,
GRADE_NAME VARCHAR2(30) NOT NULL
);
INSERT INTO USER_GRADE3 VALUES (10,'일반회원');
INSERT INTO USER_GRADE3 VALUES (20,'우수회원');
INSERT INTO USER_GRADE3 VALUES (30,'특별회원');
SELECT * FROM USER_GRADE3;
CREATE TABLE USER_USED_FK3(
USER_NO NUMBER PRIMARY KEY,
USER_ID VARCHAR2(20) UNIQUE,
USER_PWD VARCHAR2(30) NOT NULL,
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50),
GRADE_CODE NUMBER CONSTRAINT GRADE_CODE_FK3 REFERENCES USER_GRADE3 ON DELETE CASCADE
/삭제옵션/
) ;
INSERT INTO USER_USED_FK3
VALUES (1,'USER01','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr', 10);
INSERT INTO USER_USED_FK3
VALUES (2,'USER02','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr', 10);
INSERT INTO USER_USED_FK3
VALUES (3,'USER03','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr', 30);
INSERT INTO USER_USED_FK3
VALUES (4,'USER04','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr', NULL);
COMMIT;
SELECT FROM USER_GRADE3;
SELECT FROM USER_USED_FK3;
-- 부모테이블인 USER_GRADE3에서 GRADE_CODE = 10삭제
--> ON DELETE CASCADE 옵션이 설정되어 있어서 오류없이 삭제됨.
DELETE FROM USER_GRADE3
WHERE GRADE_CODE = 10;
CHECK 제약 조건 : 컬럼에 기록되는 값에 조건 설정을 할 수 있음.
CHECK(컬럼명 비교연산자 비교값)
주의 : 비교값은 리터럴만 사용할 수 있음 변하는 값이나 함수 사용 못함
CREATE TABLE USER_USED_CHECK(
USER_NO NUMBER PRIMARY KEY,
USER_ID VARCHAR2(20) UNIQUE,
USER_PWD VARCHAR2(30) NOT NULL,
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10) CONSTRAINT GENDER_CHECK CHECK(GENDER IN ('남','여')),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50)
) ;
INSERT INTO USER_USED_CHECK
VALUES (1,'USER01','PASS01','홍길동','남','010-1234-5678','hong1234@kh.or,kr');
INSERT INTO USER_USED_CHECK
VALUES (2,'USER02','PASS02','홍길동','남자','010-1234-5678','hong1234@kh.or,kr');
-- ORA-02290: 체크 제약조건(KH.GENDER_CHECK)이 위배되었습니다
-- GENDER 컬럼에 CHECK 제약조건으로 '남' 또는 '여' 만 기록 가능한데,
-- '남자'라는 조건 외 값이 들어와 에러발생
-- ** CHECK 제약조건은 범위로도 설정 가능
-- CHECK(COL 0 > AND COL <10);
CREATE TABLE USER_TEST(
USER_NO NUMBER CONSTRAINT PK_USER_TEST_NO PRIMARY KEY,
USER_ID VARCHAR2(20)CONSTRAINT UK_USER_TEST_ID UNIQUE,
USER_PWD VARCHAR2(30) CONSTRAINT NN_USER_TEST_PWD NOT NULL,
PNO CHAR(20) CONSTRAINT NN_TEST_PNO NOT NULL,
GENDER VARCHAR2(3) CONSTRAINT CK_USER_TEST_GENDER CHECK (GENDER IN ('남','여')),
PHONE VARCHAR2(20),
ADDRESS VARCHAR2(100),
STATUS VARCHAR2(3) DEFAULT 'N' CONSTRAINT NN_USER_TEST_STATUS NOT NULL,
CONSTRAINT CK_USER_TEST_STATUS CHECK(STATUS IN ('Y','N')),
CONSTRAINT UK_USER_TEST_PNO UNIQUE(PNO)
);
COMMENT ON COLUMN USER_TEST.USER_NO IS '회원번호';
COMMENT ON COLUMN USER_TEST.USER_ID IS '회원아이디';
COMMENT ON COLUMN USER_TEST.USER_PWD IS '회원비밀번호';
COMMENT ON COLUMN USER_TEST.PNO IS '주민등록번호';
COMMENT ON COLUMN USER_TEST.GENDER IS '성별';
COMMENT ON COLUMN USER_TEST.PHONE IS '연락처';
COMMENT ON COLUMN USER_TEST.ADDRESS IS '주소';
COMMENT ON COLUMN USER_TEST.STATUS IS '탈퇴여부';
INSERT INTO USER_TEST
VALUES(1,'user01','pass01',';880122-1234567','남','010-1234-1234','서울시 강남구 삼동','N');
INSERT INTO USER_TEST
VALUES(2,'user02','pass02',';890522-2644567','여','010-5678-1234','서울시 강남구 개포동','N');
INSERT INTO USER_TEST
VALUES(3,'user03','pass03',';761222-129757','남','010-1234-5678','서울시 강남구 역삼동','N');
INSERT INTO USER_TEST
VALUES(4,'user04','pass04',';880128-2145673','여','010-1234-4321','서울시 강남구 삼성동','N');
INSERT INTO USER_TEST
VALUES(5,'user05','pass05',';990122-1244867','남','010-8765-4321','성남시 수정구 태평동','N');
-- 테이블확인
SELECT * FROM USER_TEST;
SUBQUERY 를 이용한 테이블 생성
컬럼명, 데이터 타입, 값이 복사되고, 제약조건은 NOT NULL만 복사됨
1) 테이블 전체복사
CREATE TABLE EMPLOYEE_COPY
AS SELECT * FROM EMPLOYEE;
--> 서브쿼리의 조회 결과(RESELT SET)의 모양대로 테이블이 생성됨
SELECT * FROM EMPLOYEE_COPY;
2) JOIN 후 원하는 컬럼만 테이블로 복사
CREATE TABLE EMPLOYEE_COPY2
AS
SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
JOIN JOB USING(JOB_CODE);
SELECT * FROM EMPLOYEE_COPY2;
--> 서브쿼리로 테이블 생성시
-- 테이블의 형태(컬럼명,데이터타입) + NOT NULL 제약조건만 복사!
-- 제약조건, 코멘트는 복사되지 않기 때문에 별도 추가 작업이 필요하다!
제약조건 추가
-- ALTER TABLE 테이블명 ADD [CONSTRAINT 제약조건명] PRIMARY KEY(컬럼명)
-- ALTER TABLE 테이불명 ADD [CONSTRAINT 제약조건명] FOREIGN KEY(컬럼명)
-- REFERENCES 참조테이블명(참조컬럼명)
-- ALTER TABLE 테이블명 ADD [CONSTRAINT 제약조건명] UNIQUE(컬럼명)
-- ALTER TABLE 테이블명 ADD [CONSTRAINT 제약조건명] CHECK(컬럼명 비교연산자 비교값)
EMPLOYEE_COPY 테이블은 NOT NULL 제약조건만 복사됨
-- EMP_ID 컬럼에 PRIMARY KEY 제약조건 추가
ALTER TABLE EMPLOYEE_COPY ADD CONSTRAINT PK_EMP_COPY PRIMARY KEY(EMP_ID);
-- EMPLOYEE 테이블의 DEPT_CODE에 외래키 제약조건 추가
-- 참조테이블은 DEPARTMENT, 참조 컬럼은 DEPARTMENT의 기본키
ALTER TABLE EMPLOYEE ADD CONSTRAINT EMP_DEPT_CODE
FOREIGN KEY(DEPT_CODE) REFERENCES DEPARTMENT ON DELETE SET NULL;
-- EMPLOYEE 테이블의 SAL_LEVEL 외래키 제약조건 추가
-- 참조 테이블은 SAL_GRADE, 참조컬럼은 SLA_GRADE의 기본키
ALTER TABLE EMPLOYEE ADD CONSTRAINT EMP_SAL_LEVEL
FOREIGN KEY(SAL_LEVEL) REFERENCES SAL_GRADE ON DELETE SET NULL;
-- DEPARTMENT 테이블의 LOCATION_ID에 외래키 제약조건 추가
-- 참조테이블은 LOCATION, 참조 컬럼은 LOCATION 의 기본키
ALTER TABLE DEPARTMENT ADD CONSTRAINT DEPT_LOCATION_ID
FOREIGN KEY (LOCATION_ID) REFERENCES LOCATION ON DELETE SET NULL;
-- LOCATION 테이블의 NATIONAL_CODE에 외래키 제약조건 추가
-- 참조 테이블은 NATIONAL, 참조 컬럼은 NATIONAL의 기본키
ALTER TABLE LOCATION ADD CONSTRAINT LOC_NATIONAL_CODE
FOREIGN KEY (NATIONAL_CODE) REFERENCES NATIONAL ON DELETE SET NULL;