2012-06-17 8 views
6

Jestem nowicjuszem w bazach danych i bazach danych w Delphi, ucząc się ich obu za pośrednictwem materiałów instruktażowych online. Walczę z różnicą między prawdziwym życiem a przykładami, które znajduję. Aby być konkretnym, weź pod uwagę wspólne relacje Książki i Autorów w relacji wiele do wielu. Załóżmy, że masz tabelę Book (book_id, book_title itp.), Tabelę Author (author_id, author_name, itp.) I tabelę dołączania AuthorBook. Wszystkie trzy tabele będą miały unikalne identyfikatory wygenerowane automatycznie, jako klucze podstawowe.W jaki sposób można wstawiać rekordy jednocześnie do dwóch tabel bazy danych?

Przykłady zawsze zaczynają się od informacji o autorze i książce już wprowadzonych do odpowiednich tabel. Jednak w rzeczywistości, próbujemy wstawiać rekordy do obu tabel jednocześnie, , tj., użytkownicy zobaczą formularz lub siatkę z miejscami do wpisania tytułu książki i jej autora (ów). W jaki sposób coś takiego zostanie zakodowane w Delphi, zakładając kontrolę danych, bazową bazę danych Access (lub coś innego możliwego do zmienienia przez SQL)?

+4

Wstawianie do książek. Wstaw do autorów. Wstaw do tabeli łączenia. Korzystanie z Transakcji spowoduje, że proces * będzie atomowy * (ale nie * jednoczesny *). Powodzenia w Delphi/Access - Używam ORM-ów lub generowanych-DAL-ów do brudnej pracy :) –

Odpowiedz

7

Jeśli zaczynałeś od tabel takich jak te. . .

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

. . . i jeśli chcesz wstawić nową książkę i nowego autora w tym samym czasie, możesz wykonać transakcję SQL w ten sposób.

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; 

Korzystanie z pojedynczej transakcji gwarantuje, że wszystkie trzy wkładki zostaną zapisane w bazie danych lub że żaden z nich nie zostanie zapisany. Alternatywy są

  • zbudować dającym się aktualizować widok w bazie danych, łączącą wszystkie trzy tabele i wstawienie do widzenia
  • napisać procedurę przechowywaną w bazie danych, a następnie włóż poprzez procedury przechowywanej, a
  • wstawić do każdej tabeli osobno, co zakłada, że ​​istnienie książki jest ważne, nawet jeśli nie znasz autora i na odwrót. (Prawdopodobnie to bym zrobił dla książek i autorów.)

Jeśli dodawałeś nową książkę dla istniejącego autora, wykonałeś nieco inną transakcję.

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

Wyobrażam sobie, że Delphi jest jak każdy inny język po stronie klienta. Zamiast literalnych liczb całkowitych odwołujesz się do niektórych właściwości kontrolek obsługujących dane, być może do właściwości "wartości" lub "tekstu". I możesz wykonać transakcję w zdarzeniu "kliknij" przycisku.

Jeśli Delphi jest wystarczająco "świadomy danych" - za pomocą elementów sterujących, które są powiązane z kolumnami i wierszami w bazie danych, takimi jak natywne elementy kontrolne programu Access - nie trzeba wykonywać żadnych instrukcji SQL ani wykonywać żadnych czynności specjalnych w celu zapisania automatycznego Numer identyfikacyjny, który generuje dbms; będzie dostępny za pośrednictwem jednej z właściwości kontrolki. (Formularze i kontrolki programu Access są w wysokim stopniu świadome danych - tak działa ,). Ale jeśli musisz i korzystasz z dostawcy OLEDB Microsoftu dla Access, możesz użyć numeru select @@identity, aby uzyskać ostatni numer identyfikacyjny używany przez twoje połączenie.

+0

Twoja odpowiedź jest dobra, o ile znane są wartości klucza głównego. OP stwierdza: "Wszystkie trzy tabele miałyby unikalne identyfikatory, wygenerowane automatycznie, jako klucze podstawowe". Nie udało Ci się odpowiedzieć na pytanie, w jaki sposób uzyskałby podstawowe wartości kluczy dla książek i autorów do użycia w book_authors dla nowych książek lub autohrs. – crefird

+0

@ crefird: Edytowana odpowiedź. –

+0

@Catcall: Przemyślana i pomocna odpowiedź. Dziękuję za poświęcenie czasu, aby odpowiedzieć na moje pytanie. –

1

Jeśli za pomocą SQL, coś jak to (Pseudokod)

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; 

Kluczem jest wykorzystanie funkcji LastAutoInc (lub równowartość w swojej bazie danych) wewnątrz transakcji.

Powiązane problemy