본문 바로가기

MySQL/Stored Procedure

[MySQL / Stored Procedure] 에러 핸들링 (3) CONSTRAINT (上)



어떻게 에러 핸들링에 Constraint를 활용할 수 있나..


(예 : 학생이 강의를 수강하는 모델)



1. 학생이 강의를 수강


학생이 강의를 수강하려면 attending 테이블에 row를 한 개 insert 해 주면 됩니다.
이 때, 이미 수강한 과목인지.. 그리고 학생과 강의가 실제로 존재하는지 확인할 필요가 있습니다.

어떻게 할까요?


그냥 `attending` 테이블에 insert 하면 됩니다.


이미 수강한 과목이라면 `attending` 테이블의 Primary Key 제약 조건에 위배되기 때문에 1062 에러가 발생합니다.

Error: 1062


Message: Duplicate entry '%s' for key %d


학생이나 강의가 존재하지 않는다면 Foreign Key 제약 조건에 위배되는데, 부모 테이블에 row 가 존재하지 않는 경우이므로 1452 에러가 발생합니다.

Error: 1452


Message: Cannot add or update a child row: a foreign key constraint fails (%s)



2. 학생이 계정을 생성


그에 앞서 학생이 계정을 만든다면 student 테이블에 insert 합니다.

이 경우, 로그인에 사용할 이메일이 이미 존재하는지 확인해야 합니다.


그런데 student.login_email 컬럼에는 Unique Index 인 `uix-student-login_email`이 있으니, 이것도 미리 SELECT 해볼 필요가 없습니다.

insert 했을 때, 이미 존재하는 login_email 이라면 Unique Key 제약 조건에 위배되기 때문에 1062 에러가 발생하기 때문입니다.

Error: 1062


Message: Duplicate entry '%s' for key %d



3. 에러 번호만으로는 세밀하게 구분할 수 없다?


맞습니다. 학생이나 강의가 존재하지 않는다면 1452 에러가 발생하지만, 학생과 강의 중 어느쪽이 없는 것인지 구분할 수 없습니다.

비슷하게 Primary Key 중복 에러와 Unique Key 중복 에러는 둘 다 1062 에러를 발생시킵니다.


하지만 방법이 있는데, 위배한 제약 조건의 이름이 Message에 포함되어 있다는 점을 이용할 수 있습니다.


학생이 없다면 Messagefk-student-attending이 포함되고, 강의가 없다면 fk-lecture-attending이 포함됩니다.

마찬가지로 중복키 에러인 1062인 경우에도 Primary Key 중복 에러라면 PRIMARY, Unique Key 중복 에러라면 uix-student-login_email이 포함됩니다.


4. 무슨 잇점이 있을까?


첫 째로 Constraint를 사용했기 때문에 데이터의 무결성을 지킬 수 있습니다.

둘 째로 별도의 확인용 코드를 작성하지 않기 때문에 전체 코드가 심플해지고 이로 인한 성능적 잇점도 따릅니다.



다음 글에서는 Constraint 위반 에러 로그를 단순히 `error_log` 테이블에 추가하고 RESIGNAL 하는 것이 아니라, 미리 정의한 예외 코드를 리턴하고 별도의 `exception_log` 테이블에 추가하는 실제 코드를 소개하겠습니다.