Khi bắt đầu tìm hiểu một vấn đề gì mới, ai trong chúng ta cũng đều phải lần lượt chạm trán với những trục trặc từ cơ bản nhất cho đến không biết tại sao nó lại chạy được?! Nhưng chỉ có cách này thì bạn mới thực sự lĩnh hội được nó một cách trọn vẹn nhất mà thôi.

Người thành công và chuyên gia trong một lĩnh vực nào đó, thường là người phải trải qua gần như toàn bộ thất bại cũng như đối mặt với tất cả những trường hợp lỗi của thứ anh ta đang phải làm việc cùng.

Trong lĩnh vực CNTT cũng như vậy. Thậm chí đây có thể nói là yếu tố then chốt để một người kỹ sư tương lai giỏi thạo nghề và có thể ứng dụng thực tế một cách hoàn hảo những gì anh ta hiểu biết để nuôi sống tương lai mình.

Vấn đề hôm nay tôi muốn truyền tải trong bài viết này, là một câu chuyện nhỏ trong vô vàn những oái oăm mà bất cứ ai học qua Cơ sở dữ liệu đều không dưới 3 lần gặp phải. Đây là một lỗi thuộc về tính logic và liên kết, nên cũng khá cơ bản.

Nhưng dù vậy, dạo qua rất nhiều diễn đàn, thấy có nhiều người đặt câu hỏi nhưng hiếm ai trả lời một cách lịch sự và chi tiết nhất. Thế nên, tôi quyết định viết bài nho nhỏ này chia sẻ kinh nghiệm của bản thân mà thôi.

Phạm vi bài viết này, tôi minh họa với phần mềm SQL Server 2012.

Giả sử, ta có một cơ sở dữ liệu quản lý sinh viên, gồm nhiều bảng dữ liệu thuộc các nhóm khác nhau. Quá trình tạo bảng không có gì để bàn tán cả. Nhưng tôi muốn bạn lưu tâm ở vài chỗ nhỏ sau đây.

1.jpg

Hình trên bạn thấy gì? Các lệnh để tạo ra một bảng dữ liệu tên là ‘LOP’, khóa chính là anh chàng ‘MALOP’ tuyệt đối phải ‘NOT NULL’. Tiếp theo, ta quan sát lệnh tạo bảng dữ liệu tiếp theo:

2.jpg

Lệnh trong hình sẽ tạo ra một bảng dữ liệu tên là ‘SINHVIEN’, với cái KHÓA PHỤ trỏ về cái thuộc tính MALOP – vốn là khóa chính trong bảng ‘LOP’ – mà ta vừa nói ở trên đây.

Bạn xem kĩ lại 2 nhóm lệnh tạo bảng trên, hoàn toàn không có lỗi gì nhé. Tiếp, ta Execute nó…. thành công! Dĩ nhiên rồi!

Ta viết tiếp lệnh nhập dữ liệu cho cả 2 bảng trên, với thứ tự nhập liệu là bảng LOP trước, bảng SINHVIEN sau. Tại vì sao? Thuộc tính MALOP ở trong bảng LOP một khi chưa có, thì dù bạn có nỗ lực Execute bao nhiêu lần đi nữa, nó cũng báo lỗi mà thôi. Trường hợp này tôi sẽ viết một bài khác vào dịp gần thôi.

3.jpg

Bạn đếm xem, nhập liệu vậy có đúng chưa? À, không có gì sai cả. Theo như trên, thì sau khi thực thi, ta sẽ có bảng dữ liệu của LOP với 3 dòng dữ liệu đầy đủ không thiếu cột nào cả.

Ta nhập liệu tiếp cho bảng SINHVIEN:

4

Tôi bảo đảm sau khi nhấn vào nút Execute thì ngay lập tức bạn sẽ nhận được cái thông báo như trong hình bên dưới đây.

baivietcsdl5.jpg

Lỗi ta đang đối mặt:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the FOREIGN KEY

Sẽ có nhiều người khó chịu, vì thậm chí ta mới chỉ đứng ở bước nhập dữ liệu cho bảng thôi, mà đã gặp lỗi rồi. Nhưng bình tĩnh nhìn lại vấn đề, ta sẽ thấy nó thông báo không có gì ghê gớm lắm.

Cụ thể, lỗi này xảy ra do có “conflicted” – mâu thuẫn – giữa KHÓA NGOẠI ở bảng hiện tại với thuộc tính đang được dùng làm khóa ngoại, nhưng là KHÓA CHÍNH ở bảng dữ liệu kia.

Để dễ hiểu, MALOP là khóa chính trong bảng LOP, nhưng là khóa ngoại ở bảng SINHVIEN. Và mâu thuẫn sẽ xảy ra khi nào? Khi không có sự tương đồng giữa dữ liệu cả hai bên!

Tới đây, ta soi xét lại mớ dữ liệu ở bảng SINHVIEN một lần nữa (do nó dùng khóa ngoại lấy từ thuộc tính của người ta). Và tới đây, bạn sẽ soi ra vấn đề: dòng nhập liệu thứ 3, người nhập cố tình nhét vào một cái MALOP hoàn toàn chưa từng tồn tại trong bảng LOP, là giá trị ‘SH001’.

Như vậy, ta chỉ cần thay lại giá trị này bằng một giá trị đã có trong bảng LOP, hoặc thêm mã hiệu này vào bảng LOP thì trong SINHVIEN, ta có thể chạy lại mà không vướng lỗi.

The INSERT statement conflicted with the FOREIGN KEY chỉ xảy ra trong trường hợp dữ liệu nhập vào không tương thích. Hết.

VÕ TÌNH THƯƠNG

votinhthuong9@gmail.com

Advertisements