2012-06-17 12 views
6

Sono un principiante dei database e dei db di Delphi, sto imparando sia tramite materiali didattici online. Sto lottando con una differenza tra la vita reale e gli esempi che sto trovando. Per essere concreti, considerate la relazione molti-a-molti dei Libri e degli Autori. Supponi di avere una tabella di libri (book_id, book_title, ecc.), Una tabella di autori (author_id, author_name, ecc.) E una tabella di join di AuthorBook. Tutte e tre le tabelle avrebbero ID univoci, generati automaticamente, come chiavi primarie.Come si inseriscono i record contemporaneamente in due tabelle del database?

Gli esempi iniziano sempre con le informazioni su Autore e Libro già inserite nelle rispettive tabelle. Nella vita reale, tuttavia, penso che si stia tentando di inserire record in entrambe le tabelle contemporaneamente, , ovvero, gli utenti vedrebbero un modulo o una griglia con i luoghi in cui inserire il titolo di un libro e il relativo autore. In che modo qualcosa di simile potrebbe essere codificato in Delphi, presupponendo controlli basati sui dati, un database di Access sottostante (o qualcos'altro modificabile tramite SQL)?

+4

Inserisci nei libri. Inserisci negli autori. Inserisci nella tabella di join. L'uso delle transazioni renderà il processo * atomico * (ma non * simultaneo *). Buona fortuna con Delphi/Access - Io uso ORM o DAL generati per fare il lavoro sporco :) –

risposta

7

Se hai iniziato con tabelle come queste. . .

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

. . . e se è necessario inserire un nuovo libro e un nuovo autore contemporaneamente, è possibile eseguire una transazione SQL come questa.

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; 

Utilizzando una singola transazione garantisce che o tutti e tre gli inserti vengono scritti nel database o che nessuno di loro lo sono. Alternative sono

  • per costruire una visualizzazione aggiornabile nel database, unire tutti tre tabelle, ed inserendo nella vista,
  • a scrivere una stored procedure nel database, e inserire attraverso la procedura memorizzata, e
  • da inserire in ogni tabella separatamente, il che presuppone che l'esistenza del libro sia importante anche se non si conosce l'autore e viceversa. (Questo è probabilmente quello che farei per libri e autori.)

Se stavi aggiungendo un nuovo libro per un autore esistente, eseguiresti una transazione leggermente diversa.

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

Immagino che Delphi sia come qualsiasi altro linguaggio lato client qui. Invece di interi letterali, dovresti fare riferimento ad alcune proprietà dei controlli basati sui dati, forse una proprietà "valore" o "testo". E avresti eseguito la transazione nell'evento "click" di un pulsante.

Se Delphi è sufficientemente "in grado di riconoscere i dati" - utilizzando i controlli associati a colonne e righe in un database, come i controlli nativi di Access - potrebbe non essere necessario eseguire qualsiasi SQL o fare qualcosa di speciale per salvare automaticamente Numero ID generato dal dbms; sarà accessibile attraverso una delle proprietà del controllo. (Le forme e i controlli di accesso sono altamente consapevoli dei dati: è così che funzionano ). Ma se è necessario e si utilizza il provider OLEDB di Microsoft per Access, è possibile utilizzare select @@identity per ottenere l'ultimo numero ID utilizzato tramite la connessione.

+0

La tua risposta è buona finché i valori della chiave primaria sono noti. L'OP afferma "Tutte e tre le tabelle avranno ID univoci, generati automaticamente, come chiavi primarie." Non sei riuscito a capire come avrebbe ottenuto i valori delle chiavi primarie per libri e autori da usare in book_authors per nuovi libri o autohrs. – crefird

+0

@crefird: risposta modificata. –

+0

@Catcall: risposta premurosa e utile. Grazie per aver dedicato del tempo a rispondere alla mia domanda. –

1

Se si utilizza SQL, fare qualcosa di simile (pseudocodice)

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 chiave è l'uso della funzione LastAutoInc (o l'equivalente in database) all'interno di una transazione.

Problemi correlati