2012-06-17 21 views
6

Soy un novato en bases de datos y DB en Delphi, aprendiendo sobre ambos a través de materiales de instrucción en línea. Estoy luchando con una diferencia entre la vida real y los ejemplos que estoy encontrando. Para ser concreto, tenga en cuenta la relación común de muchos libros y autores. Supongamos que tiene una tabla de Libro (book_id, book_title, etc.), una tabla de Autor (author_id, author_name, etc.) y una tabla de autor de join. Las tres tablas tendrían identificadores únicos, autogenerados, como claves principales.¿Cómo se insertan los registros simultáneamente en dos tablas de bases de datos?

Los ejemplos siempre comienzan con la información de Autor y Libro ya insertada en sus respectivas tablas. En la vida real, sin embargo, creo que estaría tratando de insertar registros en ambas tablas al mismo tiempo, es decir,, los usuarios verían un formulario o una cuadrícula con lugares para ingresar el título de un libro y su autor (es). ¿Cómo se codificaría algo así en Delphi, suponiendo controles de datos, una base de datos de Access subyacente (o algo más alterable a través de SQL)?

+4

Insertar en libros. Insertar en los autores. Insertar en la tabla de unión. El uso de Transacciones hará que el proceso * atómico * (pero no * simultáneo *). Buena suerte con Delphi/Access: uso ORMs o DALs generados para hacer el trabajo sucio :) –

Respuesta

7

Si comenzó con tablas como estas. . .

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

. . . y si necesita insertar un nuevo libro y un nuevo autor al mismo tiempo, puede ejecutar una transacción SQL como esta.

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; 

El uso de una sola transacción garantiza que cualquiera de los tres insertos se escriben en la base de datos, o que ninguno de ellos son. Las alternativas son

  • para construir una vista actualizable en la base de datos, uniéndose a las tres tablas, e insertar en la vista,
  • para escribir un procedimiento almacenado en la base de datos, e insertar a través del procedimiento almacenado y
  • para insertar en cada tabla por separado, lo que supone que la existencia del libro es importante, incluso si no conoce al autor, y viceversa. (Esto es probablemente lo que haría para libros y autores.)

Si estuviera agregando un nuevo libro para un autor existente, ejecutaría una transacción ligeramente diferente.

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

Imagino que Delphi es como cualquier otro lenguaje del lado del cliente aquí. En lugar de enteros literales, haría referencia a alguna propiedad de los controles de datos, tal vez una propiedad de "valor" o "texto". Y ejecutaría la transacción en el evento de "clic" de un botón. Si Delphi es lo suficientemente "consciente de los datos" -utilizando controles vinculados a columnas y filas en una base de datos, como los controles nativos de Access-, es posible que no necesite ejecutar ningún SQL o hacer nada especial para guardar cualquier Número de ID que genera dbms; será accesible a través de una de las propiedades del control. (Los formularios y controles de Access son muy conscientes de los datos; así es como funciona ). Pero si tiene que hacerlo, y está usando el proveedor OLEDB de Microsoft para Access, puede usar select @@identity para obtener el último número de identificación utilizado a través de su conexión.

+0

Su respuesta es buena siempre y cuando se conozcan los valores de las claves primarias. El OP declara que "Las tres tablas tendrían identificadores únicos, autogenerados, como claves principales". No pudo abordar cómo obtendría los valores de las claves primarias para libros y autores para su uso en book_authors para libros nuevos o autohrs. – crefird

+0

@crefird: respuesta editada. –

+0

@Catcall: respuesta reflexiva y útil. Gracias por tomarse el tiempo para responder a mi pregunta. –

1

si utiliza SQL, hacer algo como esto (pseudocódigo)

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; 

La clave es el uso de la función LastAutoInc (o el equivalente en su base de datos) dentro de una transacción .

Cuestiones relacionadas