如何将记录同时插入两个数据库表?

时间:2012-06-17 19:09:31

标签: database delphi ms-access

我是Delphi中数据库和数据库的新手,通过在线教学材料了解这两者。我正在努力解决现实生活和我发现的例子之间的差异。具体而言,请考虑常见的书籍和作者之间的多对多关系。假设您有Book表(book_id,book_title等),Author表(author_id,author_name等)和AuthorBook连接表。所有三个表都有唯一的ID,自动生成,作为主键。

示例始终以已在各自表中插入的Author和Book信息开头。但是,在现实生活中,我认为你会尝试同时在两个表中插入记录,,用户会看到一个表单或网格,其中包含输入书名和作者的地点(s )。假设数据感知控件,底层Access数据库(或其他可通过SQL改变的东西),Delphi中如何编写类似的内容?

2 个答案:

答案 0 :(得分:7)

如果您从这些表开始。 。

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)
);

。 。 。如果您需要同时插入新书和新作者,可以像这样执行SQL事务。

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;

使用单个事务可以保证将所有三个插入都写入数据库,或者不将它们都写入数据库。替代品是

  • 在数据库中构建可更新视图,连接所有三个表,并插入到视图中,
  • 在数据库中编写存储过程,并通过存储过程插入,
  • 分别插入每个表格,假设即使您不了解作者,书籍的存在也很重要,反之亦然。 (这可能是我为书籍和作者所做的。)

如果您要为现有作者添加新书,则执行稍有不同的交易。

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

我认为Delphi就像这里的任何其他客户端语言一样。您可以引用数据感知控件的某些属性,而不是文字整数,可能是“值”或“文本”属性。并且您将在按钮的“单击”事件中执行事务。

如果Delphi足够“数据感知” - 使用绑定到数据库中的列和行的控件(如Access的本机控件) - 您可能不需要执行任何SQL或执行任何特殊操作来保存任何自动ID dbms生成的数字;它可以通过控件的一个属性访问。 (Access的表单和控件具有高度的数据感知能力;这就是他们的工作方式。)但如果您必须使用Microsoft的OLEDB提供程序进行Access,则可以使用select @@identity来获取通过您的连接使用的最后一个ID号。

答案 1 :(得分:1)

如果使用SQL,请执行此类操作(伪代码)

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;

关键是在事务中使用LastAutoInc函数(或数据库中的等效函数)