2012-06-17 37 views
6

Tôi là người mới đến cơ sở dữ liệu và db ở Delphi, tìm hiểu về cả hai thông qua tài liệu hướng dẫn trực tuyến. Tôi đang đấu tranh với sự khác biệt giữa cuộc sống thực và những ví dụ tôi đang tìm kiếm. Để được cụ thể, hãy xem xét các mối quan hệ nhiều và nhiều tác giả. Giả sử bạn đã có một bảng Sách (book_id, book_title, v.v.), một bảng Tác giả (author_id, author_name, vv) và bảng tham gia của AuthorBook. Tất cả ba bảng sẽ có ID duy nhất, được tạo tự động, làm khóa chính.Làm thế nào để chèn một bản ghi đồng thời vào hai bảng cơ sở dữ liệu?

Các ví dụ luôn bắt đầu với thông tin Tác giả và Sách đã được chèn vào trong các bảng tương ứng của chúng. Tuy nhiên, trong thực tế, tôi nghĩ bạn sẽ cố gắng chèn bản ghi vào cả hai bảng cùng một lúc, tức là, người dùng sẽ thấy biểu mẫu hoặc lưới với các địa điểm để nhập tên sách và tác giả của sách. Làm thế nào một cái gì đó như thế sẽ được mã hóa trong Delphi, giả sử điều khiển nhận thức dữ liệu, một cơ sở dữ liệu Access cơ bản (hoặc một cái gì đó khác có thể thay đổi thông qua SQL)?

+4

Chèn vào sách. Chèn vào Tác giả. Chèn vào bảng tham gia. Sử dụng Giao dịch sẽ thực hiện quy trình * nguyên tử * (nhưng không * đồng thời *). Chúc may mắn với Delphi/Access - Tôi sử dụng ORM hoặc tạo-DAL để làm công việc bẩn :) –

Trả lời

7

Nếu bạn bắt đầu với các bảng như thế này. . .

create table books (
    book_id integer primary key, 
    book_title varchar(15) not null 
); 

create table authors (
    author_id integer primary key, 
    author_name varchar(15) not null 
); 

create table book_authors (
    book_id integer not null references books (book_id), 
    author_id integer not null references authors (author_id), 
    primary key (book_id, author_id) 
); 

. . . và nếu bạn cần chèn một cuốn sách mới và một tác giả mới cùng một lúc, bạn có thể thực thi một giao dịch SQL như thế này.

begin transaction; 
insert into books values (1, 'First book'); 
insert into authors values (1, 'First author'); 
insert into book_authors (book_id, author_id) values (1, 1); 
commit; 

Sử dụng một giao dịch duy nhất đảm bảo rằng cả ba lần chèn đều được ghi vào cơ sở dữ liệu hoặc không có mã nào được chèn. Lựa chọn thay thế là

  • để xây dựng một cái nhìn có thể cập nhật trong cơ sở dữ liệu, tham gia cả ba bảng, và chèn vào xem,
  • để viết một thủ tục lưu trữ trong cơ sở dữ liệu, và chèn qua thủ tục lưu trữ, và
  • để chèn vào mỗi bảng riêng biệt, giả định rằng sự tồn tại của cuốn sách là quan trọng ngay cả khi bạn không biết tác giả và ngược lại. (Đây có lẽ là những gì tôi muốn làm cho sách và tác giả.)

Nếu bạn đang thêm một cuốn sách mới cho tác giả hiện tại, bạn thực hiện giao dịch hơi khác.

begin transaction; 
insert into books values (2, 'Second book'); 
insert into book_authors (book_id, author_id) values (2, 1); 
commit; 

Tôi tưởng tượng Delphi giống như bất kỳ ngôn ngữ phía máy khách nào khác ở đây. Thay vì các số nguyên theo nghĩa đen, bạn nên tham khảo một số thuộc tính của các điều khiển nhận biết dữ liệu, có lẽ là thuộc tính "giá trị" hoặc "văn bản". Và bạn thực hiện giao dịch trong sự kiện "nhấp" của nút. Nếu có Delphi đủ "nhận biết dữ liệu" - sử dụng các điều khiển được gắn với cột và hàng trong cơ sở dữ liệu, như điều khiển gốc của Access - bạn có thể không cần thực thi bất kỳ SQL nào hoặc làm bất cứ điều gì đặc biệt để lưu bất kỳ tự động nào Số ID mà các dbms tạo ra; nó sẽ có thể truy cập thông qua một trong các thuộc tính của điều khiển. Nhưng nếu bạn phải, và bạn đang sử dụng nhà cung cấp OLEDB của Microsoft cho Access, bạn có thể sử dụng select @@identity để lấy số id cuối cùng được sử dụng thông qua kết nối của bạn.

+0

Câu trả lời của bạn là tốt miễn là giá trị khóa chính được biết. OP nói "Tất cả ba bảng sẽ có ID duy nhất, được tạo tự động, làm khóa chính". Bạn không thể giải quyết cách anh ta sẽ nhận được các giá trị khóa chính cho sách và tác giả để sử dụng trong book_authors cho sách hoặc autohrs mới. – crefird

+0

@crefird: Câu trả lời đã chỉnh sửa. –

+0

@Catcall: Câu trả lời chu đáo và hữu ích. Cảm ơn bạn đã dành thời gian trả lời câu hỏi của tôi. –

1

Nếu sử dụng SQL, làm một cái gì đó như thế này (giả)

startTransaction; 
INSERT INTO Book VALUES('Book1'); 
bookID:=SELECT LastAutoInc FROM #Dummy; 
INSERT INTO Author VALUES('Author1'); 
authorID:=SELECT LastAutoInc FROM #Dummy; 
INSERT INTO BookAuthor VALUES(bookID, autherID); 
commit; 

Điều quan trọng là việc sử dụng các chức năng LastAutoInc (hoặc tương đương trong cơ sở dữ liệu của bạn) bên trong một giao dịch.

Các vấn đề liên quan